/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Device.cpp * Base implementation of the device class. * Copyright (C) 2005-2008 Simon Newton */ #include #include #include #include #include #include #include #include #include "ola/Logging.h" #include "olad/Device.h" #include "olad/Plugin.h" #include "olad/Port.h" #include "olad/Universe.h" namespace ola { using google::protobuf::RpcController; using google::protobuf::Closure; using std::pair; /* * Create a new device * @param owner the plugin that owns this device * @param name a nice name for this device */ Device::Device(AbstractPlugin *owner, const string &name) : AbstractDevice(), m_enabled(false), m_owner(owner), m_name(name) { } /* * Stop this device */ Device::~Device() { // we can't call stop from here because it uses virtual methods if (m_enabled) OLA_FATAL << "Device " << m_name << " wasn't stopped before deleting, " << "this represents a serious programming error."; } /* * Start the Device */ bool Device::Start() { if (m_enabled) return true; bool ret = StartHook(); if (ret) m_enabled = true; return ret; } /* * Stop this device */ bool Device::Stop() { if (!m_enabled) return true; PrePortStop(); DeleteAllPorts(); PostPortStop(); m_enabled = false; return true; } /* * Add a port to this device * @param port the port to add * @return true on success, false if the port already exists */ bool Device::AddPort(InputPort *port) { return GenericAddPort(port, &m_input_ports); } /* * Add a port to this device * @param port the port to add * @return 0 on success, non 0 on failure */ bool Device::AddPort(OutputPort *port) { return GenericAddPort(port, &m_output_ports); } void Device::InputPorts(vector *ports) const { GenericFetchPortsVector(ports, m_input_ports); } void Device::OutputPorts(vector *ports) const { GenericFetchPortsVector(ports, m_output_ports); } /* * Returns the InputPort with the id port_id */ InputPort *Device::GetInputPort(unsigned int port_id) const { map::const_iterator iter = m_input_ports.find(port_id); if (iter == m_input_ports.end()) return NULL; return iter->second; } /* * Returns the OutputPort with the id port_id */ OutputPort *Device::GetOutputPort(unsigned int port_id) const { map::const_iterator iter = m_output_ports.find(port_id); if (iter == m_output_ports.end()) return NULL; return iter->second; } /* * Delete all ports and clear the port list */ void Device::DeleteAllPorts() { map::iterator input_iter; map::iterator output_iter; for (input_iter = m_input_ports.begin(); input_iter != m_input_ports.end(); ++input_iter) { GenericDeletePort(input_iter->second); } for (output_iter = m_output_ports.begin(); output_iter != m_output_ports.end(); ++output_iter) { GenericDeletePort(output_iter->second); } m_input_ports.clear(); m_output_ports.clear(); } /* * Returns a unique id for this device */ string Device::UniqueId() const { if (m_unique_id.empty()) { if (!Owner()) { OLA_WARN << "Device: " << Name() << " missing owner"; return ""; } std::stringstream str; str << Owner()->Id() << "-" << DeviceId(); m_unique_id = str.str(); } return m_unique_id; } /* * Device Config request */ void Device::Configure(RpcController *controller, const string &request, string *response, Closure *done) { controller->SetFailed("Not Implemented"); done->Run(); (void) request; (void) response; } template bool Device::GenericAddPort(PortClass *port, map *port_map) { if (!port) return false; typename map::iterator iter = port_map->find(port->PortId()); if (iter == port_map->end()) { pair p(port->PortId(), port); port_map->insert(p); return true; } else if (iter->second != port) { OLA_WARN << "Attempt to insert a port but this port id is already " << "associated with a diferent port."; return true; } return true; } template void Device::GenericFetchPortsVector( vector *ports, const map &port_map) const { typename map::const_iterator iter; for (iter = port_map.begin(); iter != port_map.end(); ++iter) { ports->push_back(iter->second); } } template void Device::GenericDeletePort(PortClass *port) { Universe *universe = port->GetUniverse(); if (universe) universe->RemovePort(port); delete port; } } // ola