1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "communicationstarter.h"
35 #include "bluetoothlistener.h"
36 #include "trkdevice.h"
38 #include <QtCore/QTimer>
39 #include <QtCore/QEventLoop>
43 // --------------- AbstractBluetoothStarter
44 struct BaseCommunicationStarterPrivate {
45 explicit BaseCommunicationStarterPrivate(const BaseCommunicationStarter::TrkDevicePtr &d);
47 const BaseCommunicationStarter::TrkDevicePtr trkDevice;
48 BluetoothListener *listener;
54 BaseCommunicationStarter::State state;
57 BaseCommunicationStarterPrivate::BaseCommunicationStarterPrivate(const BaseCommunicationStarter::TrkDevicePtr &d) :
64 state(BaseCommunicationStarter::TimedOut)
68 BaseCommunicationStarter::BaseCommunicationStarter(const TrkDevicePtr &trkDevice, QObject *parent) :
70 d(new BaseCommunicationStarterPrivate(trkDevice))
74 BaseCommunicationStarter::~BaseCommunicationStarter()
80 void BaseCommunicationStarter::stopTimer()
82 if (d->timer && d->timer->isActive())
86 bool BaseCommunicationStarter::initializeStartupResources(QString *errorMessage)
88 errorMessage->clear();
92 BaseCommunicationStarter::StartResult BaseCommunicationStarter::start()
94 if (state() == Running) {
95 d->errorString = QLatin1String("Internal error, attempt to re-start BaseCommunicationStarter.\n");
98 // Before we instantiate timers, and such, try to open the device,
99 // which should succeed if another listener is already running in
101 if (d->trkDevice->open(&(d->errorString)))
102 return ConnectionSucceeded;
103 // Pull up resources for next attempt
105 if (!initializeStartupResources(&(d->errorString)))
109 d->timer = new QTimer;
110 connect(d->timer, SIGNAL(timeout()), this, SLOT(slotTimer()));
112 d->timer->setInterval(d->intervalMS);
113 d->timer->setSingleShot(false);
119 BaseCommunicationStarter::State BaseCommunicationStarter::state() const
124 int BaseCommunicationStarter::intervalMS() const
126 return d->intervalMS;
129 void BaseCommunicationStarter::setIntervalMS(int i)
133 d->timer->setInterval(i);
136 int BaseCommunicationStarter::attempts() const
141 void BaseCommunicationStarter::setAttempts(int a)
146 QString BaseCommunicationStarter::device() const
148 return d->trkDevice->port();
151 QString BaseCommunicationStarter::errorString() const
153 return d->errorString;
156 void BaseCommunicationStarter::slotTimer()
160 if (d->attempts >= 0 && d->n >= d->attempts) {
162 d->errorString = tr("%1: timed out after %n attempts using an interval of %2ms.", 0, d->n)
163 .arg(d->trkDevice->port()).arg(d->intervalMS);
167 // Attempt n to connect?
168 if (d->trkDevice->open(&(d->errorString))) {
170 const QString msg = tr("%1: Connection attempt %2 succeeded.").arg(d->trkDevice->port()).arg(d->n);
172 d->state = Connected;
175 const QString msg = tr("%1: Connection attempt %2 failed: %3 (retrying)...")
176 .arg(d->trkDevice->port()).arg(d->n).arg(d->errorString);
182 // --------------- AbstractBluetoothStarter
184 AbstractBluetoothStarter::AbstractBluetoothStarter(const TrkDevicePtr &trkDevice, QObject *parent) :
185 BaseCommunicationStarter(trkDevice, parent)
189 bool AbstractBluetoothStarter::initializeStartupResources(QString *errorMessage)
191 // Create the listener and forward messages to it.
192 BluetoothListener *listener = createListener();
193 connect(this, SIGNAL(message(QString)), listener, SLOT(emitMessage(QString)));
194 return listener->start(device(), errorMessage);
197 // -------- ConsoleBluetoothStarter
198 ConsoleBluetoothStarter::ConsoleBluetoothStarter(const TrkDevicePtr &trkDevice,
199 QObject *listenerParent,
201 AbstractBluetoothStarter(trkDevice, parent),
202 m_listenerParent(listenerParent)
206 BluetoothListener *ConsoleBluetoothStarter::createListener()
208 BluetoothListener *rc = new BluetoothListener(m_listenerParent);
209 rc->setMode(BluetoothListener::Listen);
210 rc->setPrintConsoleMessages(true);
214 bool ConsoleBluetoothStarter::startBluetooth(const TrkDevicePtr &trkDevice,
215 QObject *listenerParent,
217 QString *errorMessage)
219 // Set up a console starter to print to stdout.
220 ConsoleBluetoothStarter starter(trkDevice, listenerParent);
221 starter.setAttempts(attempts);
222 switch (starter.start()) {
225 case ConnectionSucceeded:
228 *errorMessage = starter.errorString();
231 // Run the starter with an event loop. @ToDo: Implement
232 // some asynchronous keypress read to cancel.
233 QEventLoop eventLoop;
234 connect(&starter, SIGNAL(connected()), &eventLoop, SLOT(quit()));
235 connect(&starter, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
236 eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
237 if (starter.state() != AbstractBluetoothStarter::Connected) {
238 *errorMessage = starter.errorString();