diff options
| author | Javier S. Pedro <maemo@javispedro.com> | 2013-03-28 13:02:18 +0100 | 
|---|---|---|
| committer | Javier S. Pedro <maemo@javispedro.com> | 2013-03-28 13:02:18 +0100 | 
| commit | cb04065d6a84bb54b485d0ad8715f09a76191412 (patch) | |
| tree | a54f4c6f2c217e3319e30bfb36f8c09f1bd2a153 /metawatch | |
| parent | 924de2248526430a8fee67582f510fc89a3786d4 (diff) | |
| download | sowatch-cb04065d6a84bb54b485d0ad8715f09a76191412.tar.gz sowatch-cb04065d6a84bb54b485d0ad8715f09a76191412.zip  | |
disable connection timer when bluetooth is off
Diffstat (limited to 'metawatch')
| -rw-r--r-- | metawatch/metawatch.cpp | 111 | ||||
| -rw-r--r-- | metawatch/metawatch.h | 41 | ||||
| -rw-r--r-- | metawatch/metawatchdigitalsimulator.cpp | 2 | ||||
| -rw-r--r-- | metawatch/metawatchdigitalsimulator.h | 2 | ||||
| -rw-r--r-- | metawatch/metawatchscanner.cpp | 12 | ||||
| -rw-r--r-- | metawatch/metawatchscanner.h | 6 | 
6 files changed, 129 insertions, 45 deletions
diff --git a/metawatch/metawatch.cpp b/metawatch/metawatch.cpp index d02e726..c287ccb 100644 --- a/metawatch/metawatch.cpp +++ b/metawatch/metawatch.cpp @@ -78,8 +78,8 @@ const quint16 MetaWatch::crcTable[256] = {  #endif  MetaWatch::MetaWatch(ConfigKey* settings, QObject* parent) : -    Watch(parent), -    _settings(settings->getSubkey(QString(), this)), +	Watch(parent), +	_settings(settings->getSubkey(QString(), this)),  	_idleTimer(new QTimer(this)), _ringTimer(new QTimer(this)),  	_watchTime(), _watchBattery(0), _watchBatteryAverage(0), _watchCharging(false),  	_currentMode(IdleMode),	_paintMode(IdleMode), @@ -87,9 +87,11 @@ MetaWatch::MetaWatch(ConfigKey* settings, QObject* parent) :  	_connectRetries(0),	_connected(false),  	_connectTimer(new QTimer(this)),  	_connectAlignedTimer(new QSystemAlignedTimer(this)), +	_localDev(new QBluetoothLocalDevice(this)),  	_socket(0),  	_sendTimer(new QTimer(this))  { +	// Read current device settings  	connect(_settings, SIGNAL(subkeyChanged(QString)), SLOT(settingChanged(QString)));  	_address = QBluetoothAddress(settings->value("address").toString()); @@ -99,6 +101,7 @@ MetaWatch::MetaWatch(ConfigKey* settings, QObject* parent) :  	_buttonNames << "A" << "B" << "C" << "D" << "E" << "F"; +	// Configure timers (but do not turn them on yet)  	_idleTimer->setInterval(_notificationTimeout * 1000);  	_idleTimer->setSingleShot(true);  	connect(_idleTimer, SIGNAL(timeout()), SIGNAL(idling())); @@ -114,8 +117,17 @@ MetaWatch::MetaWatch(ConfigKey* settings, QObject* parent) :  	_sendTimer->setInterval(DelayBetweenMessages);  	connect(_sendTimer, SIGNAL(timeout()), SLOT(timedSend())); -	// Do an initial connection attempt after a short delay -	_connectTimer->start(100); +	// Connect other signals +	connect(_localDev, SIGNAL(hostModeStateChanged(QBluetoothLocalDevice::HostMode)), SLOT(localDevModeChanged(QBluetoothLocalDevice::HostMode))); + +	// Check to see if we can connect right away +	if (_localDev->hostMode() != QBluetoothLocalDevice::HostPoweredOff) { +		// Do an initial connection attempt after a short delay +		// (To give time for other plugins to initialize, etc.) +		scheduleConnect(); +	} else { +		qDebug() << "Not starting MetaWatch connection because BT is off"; +	}  }  MetaWatch::~MetaWatch() @@ -170,7 +182,7 @@ void MetaWatch::setDateTime(const QDateTime &dateTime)  	msg.data[1] = date.year() & 0xFF;  	msg.data[2] = date.month();  	msg.data[3] = date.day(); -	// Qt week starts on Monday([1-7]), MW starts on Sunday([0-6]). +	// Qt week starts on Monday([1-7]), MetaWatch week starts on Sunday([0-6]).  	msg.data[4] = date.dayOfWeek() % 7;  	msg.data[5] = time.hour();  	msg.data[6] = time.minute(); @@ -322,9 +334,53 @@ quint16 MetaWatch::calcCrc(const Message& msg)  	return calcCrc(data, msgSize + 4);  } -void MetaWatch::retryConnect() +void MetaWatch::scheduleConnect() +{ +	if (_connected || +	        _connectAlignedTimer->isActive() || _connectTimer->isActive()) { +		// Already connected or already scheduled to connect. +		return; +	} + +	_connectRetries = 0; +	_connectTimer->start(100); +} + +void MetaWatch::scheduleRetryConnect() +{ +	if (_connected || +	        _connectAlignedTimer->isActive() || _connectTimer->isActive()) { +		// Already connected or already scheduled to connect. +		return; +	} + +	int timeToNextRetry; +	if (_connectRetries >= connectRetryTimesSize) { +		timeToNextRetry = connectRetryTimes[connectRetryTimesSize - 1]; +	} else { +		timeToNextRetry = connectRetryTimes[_connectRetries]; +		_connectRetries++; // Increase the number of connection attemps +	} + +	qDebug() << "Backing off for" << timeToNextRetry << "seconds for next retry"; +	_connectAlignedTimer->start(timeToNextRetry / 2, timeToNextRetry * 2); +	if (_connectAlignedTimer->lastError() != QSystemAlignedTimer::NoError) { +		// Hopefully a future version of QSystemAlignedTimer implements this fallback +		// For now, we have to do it ourselves. +		qDebug() << "Note: using plain QTimer for retry"; +		_connectTimer->start(timeToNextRetry * 1000); +	} +} + +void MetaWatch::unscheduleConnect()  { -	delete _socket; +	_connectAlignedTimer->stop(); +	_connectTimer->stop(); +} + +void MetaWatch::connectToWatch() +{ +	delete _socket; //Delete socket from previous connect if any.  	_socket = new QBluetoothSocket(QBluetoothSocket::RfcommSocket);  	connect(_socket, SIGNAL(connected()), SLOT(socketConnected())); @@ -608,7 +664,8 @@ void MetaWatch::handleNvalOperationMessage(const Message& msg)  		// Check if there's a pending write for this nval.  		if (_nvals.contains(value)) {  			int new_data = _nvals[value]; -			qDebug() << "nval" << hex << value << "currently =" << dec << data << "is pending write to =" << new_data; +			qDebug() << "nval" << hex << value << "currently =" << dec << data +			         << "is pending write to =" << new_data;  			if (new_data != data) {  				realNvalWrite(value, _nvals[value]);  			} else { @@ -706,6 +763,23 @@ void MetaWatch::settingChanged(const QString &key)  	}  } +void MetaWatch::localDevModeChanged(QBluetoothLocalDevice::HostMode state) +{ +	qDebug() << "Local bluetooth device mode changed to" << state; +	if (state == QBluetoothLocalDevice::HostPoweredOff) { +		// Host bluetooth was powered down +		// Assume the socket has been disconnected +		socketDisconnected(); +		// Cancel any pending connection attempts +		unscheduleConnect(); +	} else { +		// Host bluetooth might have been powered up +		if (!_connected) { +			scheduleConnect(); +		} +	} +} +  void MetaWatch::socketConnected()  {  	if (!_connected) { @@ -734,6 +808,7 @@ void MetaWatch::socketConnected()  void MetaWatch::socketDisconnected()  { +	// Signal disconnection if necessary  	if (_connected) {  		qDebug() << "disconnected"; @@ -744,19 +819,9 @@ void MetaWatch::socketDisconnected()  		emit disconnected();  	} -	int timeToNextRetry; -	if (_connectRetries >= connectRetryTimesSize) { -		timeToNextRetry = connectRetryTimes[connectRetryTimesSize - 1]; -	} else { -		timeToNextRetry = connectRetryTimes[_connectRetries]; -		_connectRetries++; -	} -	qDebug() << "Backing off for" << timeToNextRetry << "seconds for next retry"; -	_connectAlignedTimer->start(timeToNextRetry / 2, timeToNextRetry * 2); -	if (_connectAlignedTimer->lastError() != QSystemAlignedTimer::NoError) { -		// I would like to know why QtM couldn't _emulate_ here using a QTimer by itself. -		qDebug() << "Note: using plain QTimer for retry"; -		_connectTimer->start(timeToNextRetry * 1000); +	// Setup reconnection attempt if necessary +	if (_localDev->hostMode() != QBluetoothLocalDevice::HostPoweredOff) { +		scheduleRetryConnect();  	}  } @@ -768,6 +833,8 @@ void MetaWatch::socketData()  void MetaWatch::socketError(QBluetoothSocket::SocketError error)  {  	qWarning() << "Socket error:" << error; +	// Seems that sometimes a disconnection event may not be generated. +	socketDisconnected();  }  void MetaWatch::socketState(QBluetoothSocket::SocketState error) @@ -777,7 +844,7 @@ void MetaWatch::socketState(QBluetoothSocket::SocketState error)  void MetaWatch::timedReconnect()  { -	retryConnect(); +	connectToWatch();  }  void MetaWatch::timedSend() diff --git a/metawatch/metawatch.h b/metawatch/metawatch.h index 8946884..5d7534a 100644 --- a/metawatch/metawatch.h +++ b/metawatch/metawatch.h @@ -6,15 +6,17 @@  #include <QtCore/QSettings>  #include <QtConnectivity/QBluetoothAddress>  #include <QtConnectivity/QBluetoothSocket> +#include <QtConnectivity/QBluetoothLocalDevice>  #include <QtSystemInfo/QSystemAlignedTimer>  #include <sowatch.h> +namespace sowatch +{ +  using QTM_PREPEND_NAMESPACE(QBluetoothSocket);  using QTM_PREPEND_NAMESPACE(QBluetoothAddress);  using QTM_PREPEND_NAMESPACE(QSystemAlignedTimer); - -namespace sowatch -{ +using QTM_PREPEND_NAMESPACE(QBluetoothLocalDevice);  class MetaWatchPaintEngine; @@ -138,6 +140,17 @@ public:  	void ungrabButton(Mode mode, Button button);  protected: +	// Base watch protocol stuff +	struct Message { +		MessageType type; +		quint8 options; +		QByteArray data; +		Message(MessageType ntype = NoMessage, QByteArray ndata = QByteArray(), quint8 noptions = 0) : +			type(ntype), options(noptions), data(ndata) +		{ } +	}; + +protected:  	ConfigKey *_settings;  	// Some configurable stuff. @@ -159,12 +172,13 @@ protected:  	short _watchBatteryAverage;  	bool _watchCharging;  	Mode _currentMode; +	/** The mode where paint operations done using QPaintDevice go into */  	Mode _paintMode;  	// Required by QPaintDevice  	mutable MetaWatchPaintEngine* _paintEngine; -	/** The shadow framebuffers for each of the watch modes */ +	/** The framebuffers for each of the watch modes */  	QImage _image[3];  	// Timers to retry the connection when the watch is not found. @@ -176,19 +190,10 @@ protected:  	QSystemAlignedTimer* _connectAlignedTimer;  	// Connection stuff +	QBluetoothLocalDevice* _localDev;  	QBluetoothAddress _address;  	QBluetoothSocket* _socket; -	// Base watch protocol stuff -	struct Message { -		MessageType type; -		quint8 options; -		QByteArray data; -		Message(MessageType ntype = NoMessage, QByteArray ndata = QByteArray(), quint8 noptions = 0) : -			type(ntype), options(noptions), data(ndata) -		{ } -	}; -  	/** The "packets to be sent" asynchronous queue **/  	QQueue<Message> _toSend;  	QTimer* _sendTimer; @@ -202,8 +207,13 @@ protected:  	static quint16 calcCrc(const QByteArray& data, int size);  	static quint16 calcCrc(const Message& msg); +	/** Reprime the connection retry timers. */ +	void scheduleConnect(); +	void scheduleRetryConnect(); +	void unscheduleConnect(); +  	/** Attempt a connection to the watch. */ -	virtual void retryConnect(); +	virtual void connectToWatch();  	/** Sends a message to the watch. Does not block. */  	virtual void send(const Message& msg); @@ -239,6 +249,7 @@ protected:  private slots:  	void settingChanged(const QString& key); +	void localDevModeChanged(QBluetoothLocalDevice::HostMode state);  	void socketConnected();  	void socketDisconnected();  	void socketData(); diff --git a/metawatch/metawatchdigitalsimulator.cpp b/metawatch/metawatchdigitalsimulator.cpp index e5cd74b..dabc0f3 100644 --- a/metawatch/metawatchdigitalsimulator.cpp +++ b/metawatch/metawatchdigitalsimulator.cpp @@ -100,7 +100,7 @@ void MetaWatchDigitalSimulator::vibrate(bool on)  	qDebug() << "vibrate" << on;  } -void MetaWatchDigitalSimulator::retryConnect() +void MetaWatchDigitalSimulator::connectToWatch()  {  	if (!_connected && _form) {  		qDebug() << "simulator connected"; diff --git a/metawatch/metawatchdigitalsimulator.h b/metawatch/metawatchdigitalsimulator.h index de2efdd..8b424ec 100644 --- a/metawatch/metawatchdigitalsimulator.h +++ b/metawatch/metawatchdigitalsimulator.h @@ -26,7 +26,7 @@ public:  	void vibrate(bool on); -	void retryConnect(); +	void connectToWatch();  	void send(const Message& msg);  private slots: diff --git a/metawatch/metawatchscanner.cpp b/metawatch/metawatchscanner.cpp index 6a65419..1e43115 100644 --- a/metawatch/metawatchscanner.cpp +++ b/metawatch/metawatchscanner.cpp @@ -30,17 +30,23 @@ void MetaWatchScanner::handleDiscoveredService(const QBluetoothServiceInfo &info  {  	const QBluetoothDeviceInfo dev = info.device();  	QString deviceName = dev.name(); -	if (deviceName.contains("MetaWatch", Qt::CaseInsensitive)) { +	if (deviceName.startsWith("MetaWatch", Qt::CaseInsensitive)) {  		QVariantMap foundInfo;  		foundInfo["address"] = dev.address().toString();  		foundInfo["name"] = deviceName;  		qDebug() << "metawatch bluetooth scan found:" << deviceName; +		// "MetaWatch Digital" was AU2000 with preSTRATA firmware +		// "MetaWatch SW12" seems to be STRATA +		// "MetaWatch 99" seems to be AU2000 with STRATA firmware  		if (deviceName.contains("Digital", Qt::CaseInsensitive) || -		        deviceName.contains("SW12", Qt::CaseInsensitive)) { +		        deviceName.contains("SW12") || deviceName.contains("99")) {  			foundInfo["driver"] = QString("metawatch-digital");  			foundInfo["next-watchlet-button"] = QString("A");  			emit watchFound(foundInfo); -		} else if (deviceName.contains("Analog", Qt::CaseInsensitive)) { +		// "MetaWatch Analog" is the only analog watch released so far, preSTRATA fw +		// "MetaWatch WDS111" (seems) analog watch with STRATA fw +		} else if (deviceName.contains("Analog", Qt::CaseInsensitive) || +		           deviceName.contains("WDS111", Qt::CaseInsensitive)) {  			foundInfo["driver"] = QString("metawatch-analog");  			foundInfo["next-watchlet-button"] = QString("A");  			emit watchFound(foundInfo); diff --git a/metawatch/metawatchscanner.h b/metawatch/metawatchscanner.h index c98bf1a..a41633a 100644 --- a/metawatch/metawatchscanner.h +++ b/metawatch/metawatchscanner.h @@ -4,12 +4,12 @@  #include <sowatch.h>  #include <QtConnectivity/QBluetoothServiceDiscoveryAgent> -using QTM_PREPEND_NAMESPACE(QBluetoothServiceDiscoveryAgent); -using QTM_PREPEND_NAMESPACE(QBluetoothServiceInfo); -  namespace sowatch  { +using QTM_PREPEND_NAMESPACE(QBluetoothServiceDiscoveryAgent); +using QTM_PREPEND_NAMESPACE(QBluetoothServiceInfo); +  class MetaWatchScanner : public WatchScanner  {  	Q_OBJECT  | 
