source: SMSSender/gateways/Smartphone/business/smartphoneconnector.cpp @ 374:159b8dc48877

separation-frontend-backend
Last change on this file since 374:159b8dc48877 was 374:159b8dc48877, checked in by Sämy Zehnder <saemy.zehnder@…>, 5 years ago
  • Code cleanup in some classes.
File size: 5.0 KB
Line 
1/*
2  Smartphone plugin - The smssender plugin for connecting to smartphones.
3  Copyright (C) 2012-2014, gorrión. See http://smssender.gorrion.ch
4
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  GNU General Public License for more details.
14
15  You should have received a copy of the GNU General Public License
16  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17*/
18#include "smartphoneconnector.h"
19
20#include <QNetworkInterface>
21
22#include "common/exceptions/eexception.h"
23#include "gateways/Smartphone/business/connectionhandler.h"
24#include "gateways/Smartphone/business/packages/packagewizard.h"
25#include "gateways/Smartphone/business/smartphonemanager.h"
26
27namespace Smartphone {
28
29SmartphoneConnector::SmartphoneConnector(SmartphoneManager *smartphoneManager)
30    : QObject()
31    , m_smartphoneManager(smartphoneManager)
32{
33    m_server = new QTcpServer(this);
34    bool open = m_server->listen(QHostAddress::Any, PORT_SMSSENDER_APP);
35    if (!open) {
36        EException(QString("Unable to open server socket: %1")
37                       .arg(m_server->errorString()))
38                .raise();
39    }
40
41    connect(m_server, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
42
43
44    // Client polling setup
45    startClientPoll();
46
47    m_pollerTimer.setInterval(5000);
48    connect(&m_pollerTimer, SIGNAL(timeout()), this, SLOT(startClientPoll()));
49    m_pollerTimer.start();
50}
51SmartphoneConnector::~SmartphoneConnector() {
52    qDeleteAll(m_connections.values());
53    m_deviceConnections.clear();
54}
55
56
57/**
58 * Returns the XML-String with the connection-request data that a smartphone needs to be able
59 * to connect to us.
60 */
61QString SmartphoneConnector::createConnectionRequestPackage(const Smartphone &device) const {
62    // Get the pcIdent
63    QString pcIdent = m_smartphoneManager->pcIdent();
64
65    // Get the readable name
66    QString name = m_smartphoneManager->pcName();
67
68    return PackageWizard::createConnectionRequestPackage(pcIdent, name, device);
69}
70
71
72void SmartphoneConnector::acceptConnection() {
73    QTcpSocket *cSocket = m_server->nextPendingConnection();
74    handleSocket(cSocket);
75}
76
77void SmartphoneConnector::handleSocket(QTcpSocket *cSocket) {
78    handleSocket(cSocket, NULL);
79}
80void SmartphoneConnector::handleSocket(QTcpSocket *cSocket, const Smartphone &peerDevice) {
81    QHostAddress peerAddress = cSocket->peerAddress();
82    if (m_connections.contains(peerAddress)) {
83        cSocket->close(); // Do not open multiple sockets to the same device
84        delete cSocket;
85        return;
86    }
87
88    ConnectionHandler *handler = new ConnectionHandler(m_smartphoneManager, cSocket, peerDevice);
89    connect(handler, SIGNAL(peerIdentified(ConnectionHandler*)), this, SLOT(onPeerIdentified(ConnectionHandler*)));
90    connect(handler, SIGNAL(aboutToFinish(ConnectionHandler*)),
91            this, SLOT(onSocketHandlerFinished(ConnectionHandler*)), Qt::DirectConnection);
92    m_connections.insert(peerAddress, handler);
93}
94
95
96void SmartphoneConnector::onPeerIdentified(ConnectionHandler *connectionHandler) {
97    Q_ASSERT(connectionHandler->isPeerIdentified());
98    registerDeviceConnection(connectionHandler->peerDevice(), connectionHandler);
99}
100void SmartphoneConnector::onSocketHandlerFinished(ConnectionHandler *connectionHandler) {
101    unregisterDeviceConnection(connectionHandler->peerDevice());
102
103    for (QHash<QHostAddress, ConnectionHandler *>::iterator i = m_connections.begin(); i != m_connections.end(); ++i) {
104        if (i.value() == connectionHandler) {
105            m_connections.remove(i.key());
106            break;
107        }
108    }
109}
110
111void SmartphoneConnector::registerDeviceConnection(const Smartphone &device, ConnectionHandler *handler) {
112    if (m_deviceConnections.contains(device)) {
113        if (m_deviceConnections[device] != handler) {
114            handler->cancelWork();
115            return;
116        }
117    } else {
118        m_deviceConnections.insert(device, handler);
119    }
120
121    emit deviceConnected(device);
122}
123void SmartphoneConnector::unregisterDeviceConnection(const Smartphone &device) {
124    if (!m_deviceConnections.contains(device)) {
125        return;
126    }
127
128    m_deviceConnections.take(device);
129    emit deviceDisconnected(device);
130}
131
132QSet<Smartphone> SmartphoneConnector::connectedDevices() const {
133    return m_deviceConnections.keys().toSet();
134}
135bool SmartphoneConnector::isDeviceConnected(const Smartphone &device) const {
136    return m_deviceConnections.contains(device);
137}
138
139const ConnectionHandler * SmartphoneConnector::connectionHandler(const QHostAddress &address) const {
140    return m_connections.value(address);
141}
142const ConnectionHandler * SmartphoneConnector::connectionHandler(const Smartphone &device) const {
143    return m_deviceConnections.value(device);
144}
145
146
147}
Note: See TracBrowser for help on using the repository browser.