/*===================================================================== QGroundControl Open Source Ground Control Station (c) 2009, 2010 QGROUNDCONTROL PROJECT This file is part of the QGROUNDCONTROL project QGROUNDCONTROL 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 3 of the License, or (at your option) any later version. QGROUNDCONTROL 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 General Public License for more details. You should have received a copy of the GNU General Public License along with QGROUNDCONTROL. If not, see . ======================================================================*/ /** * @file * @brief Brief Description * * @author Lorenz Meier * */ #include #include #include "LinkManager.h" #include #include LinkManager* LinkManager::instance() { static LinkManager* _instance = 0; if(_instance == 0) { _instance = new LinkManager(); /* Set the application as parent to ensure that this object * will be destroyed when the main application exits */ _instance->setParent(qApp); } return _instance; } /** * @brief Private singleton constructor * * This class implements the singleton design pattern and has therefore only a private constructor. **/ LinkManager::LinkManager() { links = QList(); protocolLinks = QMap(); } LinkManager::~LinkManager() { disconnectAll(); dataMutex.lock(); foreach (LinkInterface* link, links) { if(link) link->deleteLater(); } dataMutex.unlock(); } void LinkManager::add(LinkInterface* link) { dataMutex.lock(); if (!links.contains(link)) { if(!link) return; connect(link, SIGNAL(destroyed(QObject*)), this, SLOT(removeObj(QObject*))); links.append(link); dataMutex.unlock(); emit newLink(link); } else { dataMutex.unlock(); } } void LinkManager::addProtocol(LinkInterface* link, ProtocolInterface* protocol) { // Connect link to protocol // the protocol will receive new bytes from the link if (!link || !protocol) return; dataMutex.lock(); QList linkList = protocolLinks.values(protocol); // If protocol has not been added before (list length == 0) // OR if link has not been added to protocol, add if (!linkList.contains(link)) { // Protocol is new, add connect(link, SIGNAL(bytesReceived(LinkInterface*, QByteArray)), protocol, SLOT(receiveBytes(LinkInterface*, QByteArray))); // Add status connect(link, SIGNAL(connected(bool)), protocol, SLOT(linkStatusChanged(bool))); // Store the connection information in the protocol links map protocolLinks.insertMulti(protocol, link); dataMutex.unlock(); // Make sure the protocol clears its metadata for this link. protocol->resetMetadataForLink(link); } else { dataMutex.unlock(); } //qDebug() << __FILE__ << __LINE__ << "ADDED LINK TO PROTOCOL" << link->getName() << protocol->getName() << "NEW SIZE OF LINK LIST:" << protocolLinks.size(); } QList LinkManager::getLinksForProtocol(ProtocolInterface* protocol) { dataMutex.lock(); QList links = protocolLinks.values(protocol); dataMutex.unlock(); return links; } ProtocolInterface* LinkManager::getProtocolForLink(LinkInterface* link) { dataMutex.lock(); ProtocolInterface* interface = protocolLinks.key(link); dataMutex.unlock(); return interface; } bool LinkManager::connectAll() { bool allConnected = true; dataMutex.lock(); foreach (LinkInterface* link, links) { if(!link) {} else if(!link->connect()) allConnected = false; } dataMutex.unlock(); return allConnected; } bool LinkManager::disconnectAll() { bool allDisconnected = true; dataMutex.lock(); foreach (LinkInterface* link, links) { //static int i=0; if(!link) {} else if(!link->disconnect()) allDisconnected = false; } dataMutex.unlock(); return allDisconnected; } bool LinkManager::connectLink(LinkInterface* link) { if(!link) return false; return link->connect(); } bool LinkManager::disconnectLink(LinkInterface* link) { if(!link) return false; return link->disconnect(); } void LinkManager::removeObj(QObject* link) { LinkInterface* linkInterface = dynamic_cast(link); if (linkInterface) { removeLink(linkInterface); } } bool LinkManager::removeLink(LinkInterface* link) { if(link) { dataMutex.lock(); for (int i=0; i < QList(links).size(); i++) { if(link==links.at(i)) { links.removeAt(i); //remove from link list } } // Remove link from protocol map QList protocols = protocolLinks.keys(link); foreach (ProtocolInterface* proto, protocols) { protocolLinks.remove(proto, link); } dataMutex.unlock(); // Emit removal of link emit linkRemoved(link); return true; } return false; } /** * The access time is linear in the number of links. * * @param id link identifier to search for * @return A pointer to the link or NULL if not found */ LinkInterface* LinkManager::getLinkForId(int id) { dataMutex.lock(); LinkInterface* linkret = NULL; foreach (LinkInterface* link, links) { if (link->getId() == id) { linkret = link; } } dataMutex.unlock(); return linkret; } /** * */ const QList LinkManager::getLinks() { dataMutex.lock(); QList ret(links); dataMutex.unlock(); return ret; } const QList LinkManager::getSerialLinks() { dataMutex.lock(); QList s; foreach (LinkInterface* i, links) { SerialLink* link = qobject_cast(i); if (link) s.append(link); } dataMutex.unlock(); return s; }