Skip to content
Snippets Groups Projects
LinkManager.cc 5.37 KiB
Newer Older
  • Learn to ignore specific revisions
  • pixhawk's avatar
    pixhawk committed
    /*=====================================================================
    
    lm's avatar
    lm committed
    
    QGroundControl Open Source Ground Control Station
    
    (c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
    
    This file is part of the QGROUNDCONTROL project
    
        QGROUNDCONTROL is free software: you can redistribute it and/or modify
    
    pixhawk's avatar
    pixhawk committed
        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.
    
    lm's avatar
    lm committed
    
        QGROUNDCONTROL is distributed in the hope that it will be useful,
    
    pixhawk's avatar
    pixhawk committed
        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.
    
    pixhawk's avatar
    pixhawk committed
        You should have received a copy of the GNU General Public License
    
    lm's avatar
    lm committed
        along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
    
    
    pixhawk's avatar
    pixhawk committed
    ======================================================================*/
    
    pixhawk's avatar
    pixhawk committed
    /**
     * @file
     *   @brief Brief Description
     *
     *   @author Lorenz Meier <mavteam@student.ethz.ch>
     *
     */
    
    #include <QList>
    #include <QApplication>
    
    #include "LinkManager.h"
    #include "MainWindow.h"
    
    Don Gagne's avatar
    Don Gagne committed
    #include "QGCMessageBox.h"
    
    #include "QGCApplication.h"
    
    Don Gagne's avatar
    Don Gagne committed
    IMPLEMENT_QGC_SINGLETON(LinkManager, LinkManager)
    
    pixhawk's avatar
    pixhawk committed
    /**
     * @brief Private singleton constructor
    
    pixhawk's avatar
    pixhawk committed
     * This class implements the singleton design pattern and has therefore only a private constructor.
     **/
    
    Don Gagne's avatar
    Don Gagne committed
    LinkManager::LinkManager(QObject* parent) :
        QGCSingleton(parent),
    
        _connectionsSuspended(false)
    
    pixhawk's avatar
    pixhawk committed
    {
    
    pixhawk's avatar
    pixhawk committed
    }
    
    LinkManager::~LinkManager()
    {
    
        Q_ASSERT_X(_links.count() == 0, "LinkManager", "LinkManager::_shutdown should have been called previously");
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    void LinkManager::addLink(LinkInterface* link)
    
    pixhawk's avatar
    pixhawk committed
    {
    
        // Take ownership for delete
        link->_ownedByLinkManager = true;
        
    
        _linkListMutex.lock();
    
        if (!_links.contains(link)) {
    
            _links.append(link);
    
            _linkListMutex.unlock();
    
            _linkListMutex.unlock();
    
        // MainWindow may be around when doing things like running unit tests
        if (MainWindow::instance()) {
            connect(link, SIGNAL(communicationError(QString,QString)), MainWindow::instance(), SLOT(showCriticalMessage(QString,QString)), Qt::QueuedConnection);
    
        MAVLinkProtocol* mavlink = MAVLinkProtocol::instance();
        connect(link, &LinkInterface::bytesReceived, mavlink, &MAVLinkProtocol::receiveBytes);
        connect(link, &LinkInterface::connected, mavlink, &MAVLinkProtocol::linkConnected);
        connect(link, &LinkInterface::disconnected, mavlink, &MAVLinkProtocol::linkDisconnected);
        mavlink->resetMetadataForLink(link);
    
    pixhawk's avatar
    pixhawk committed
    
    bool LinkManager::connectAll()
    {
    
        if (_connectionsSuspendedMsg()) {
            return false;
        }
        
    
        bool allConnected = true;
    
    
        _linkListMutex.lock();
    
        foreach (LinkInterface* link, _links) {
            Q_ASSERT(link);
            if (!link->_connect()) {
                allConnected = false;
            }
    
        _linkListMutex.unlock();
    
    
        return allConnected;
    
    pixhawk's avatar
    pixhawk committed
    }
    
    bool LinkManager::disconnectAll()
    {
    
        bool allDisconnected = true;
    
    
        _linkListMutex.lock();
    
        foreach (LinkInterface* link, _links)
    
    Lorenz Meier's avatar
    Lorenz Meier committed
        {
    
            if (!link->_disconnect()) {
    
                allDisconnected = false;
            }
    
        _linkListMutex.unlock();
    
    
        return allDisconnected;
    
    pixhawk's avatar
    pixhawk committed
    }
    
    bool LinkManager::connectLink(LinkInterface* link)
    {
    
        Q_ASSERT(link);
        
        if (_connectionsSuspendedMsg()) {
            return false;
        }
    
        return link->_connect();
    
    pixhawk's avatar
    pixhawk committed
    }
    
    bool LinkManager::disconnectLink(LinkInterface* link)
    {
    
        Q_ASSERT(link);
        return link->_disconnect();
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    void LinkManager::deleteLink(LinkInterface* link)
    
        Q_ASSERT(link);
    
        _linkListMutex.lock();
    
        
        Q_ASSERT(_links.contains(link));
        _links.removeOne(link);
        Q_ASSERT(!_links.contains(link));
    
    
        _linkListMutex.unlock();
    
    Don Gagne's avatar
    Don Gagne committed
        // Emit removal of link
    
        emit linkDeleted(link);
        
        Q_ASSERT(link->_ownedByLinkManager);
        link->_deletedByLinkManager = true;   // Signal that this is a valid delete
        delete link;
    
    pixhawk's avatar
    pixhawk committed
    }
    
    /**
     *
     */
    const QList<LinkInterface*> LinkManager::getLinks()
    {
    
        _linkListMutex.lock();
    
        QList<LinkInterface*> ret(_links);
    
        _linkListMutex.unlock();
    
    pixhawk's avatar
    pixhawk committed
    }
    
    
    const QList<SerialLink*> LinkManager::getSerialLinks()
    {
    
        _linkListMutex.lock();
    
        QList<SerialLink*> s;
    
    
        foreach (LinkInterface* link, _links)
    
            Q_ASSERT(link);
            
            SerialLink* serialLink = qobject_cast<SerialLink*>(link);
    
            if (serialLink)
                s.append(serialLink);
    
        _linkListMutex.unlock();
    
    
    /// @brief If all new connections should be suspended a message is displayed to the user and true
    ///         is returned;
    bool LinkManager::_connectionsSuspendedMsg(void)
    {
        if (_connectionsSuspended) {
    
    Don Gagne's avatar
    Don Gagne committed
            QGCMessageBox::information(tr("Connect not allowed"),
                                       tr("Connect not allowed: %1").arg(_connectionsSuspendedReason));
    
            return true;
        } else {
            return false;
        }
    }
    
    void LinkManager::setConnectionsSuspended(QString reason)
    {
        _connectionsSuspended = true;
        _connectionsSuspendedReason = reason;
        Q_ASSERT(!reason.isEmpty());
    }
    
    
    void LinkManager::_shutdown(void)
    {
        QList<LinkInterface*> links = _links;
        foreach(LinkInterface* link, links) {
            disconnectLink(link);
            deleteLink(link);
        }
    }