Source

Target

Commits (10)
Showing with 191 additions and 30 deletions
Qt 5.4 introduces many new features and improvements as well as bugfixes
over the 5.3.x series. For more details, refer to the online documentation
included in this distribution. The documentation is also available online:
http://qt-project.org/doc/qt-5.4
The Qt version 5.4 series is binary compatible with the 5.3.x series.
Applications compiled for 5.3 will continue to run with 5.4.
Some of the changes listed in this file include issue tracking numbers
corresponding to tasks in the Qt Bug Tracker:
http://bugreports.qt-project.org/
Each of these identifiers can be entered in the bug tracker to obtain more
information about a particular change.
****************************************************************************
* Library *
****************************************************************************
QtBluetooth
-----------
- Bluetooth Low Energy Support added:
* Connect/disconnect to peripherals supported.
* Services on Peripheral can be discovered and interacted with.
* BlueZ on Linux is the only currently supported platform.
Minimal requirement are a Linux kernel v 3.5+ and BlueZ version 4.101+.
More platforms will be added by future Qt releases.
* The feature/API remains in Tech Preview stage throughout the Qt 5.4
release. Some API elements may still change in future releases.
- Fixed documentation throughout all classes.
- General:
* Bluetooth Low Energy scanner example has been added.
* Heart Listener Bluetooth Low Energy Heart Belt example has been added.
- QBluetoothAddress:
* QDebug streaming operator added.
- QBluetoothDeviceInfo:
* QBluetooth::CoreConfiguration enum added.
* CoreConfiguration attribute added.
- QBluetoothServiceDiscoveryAgent:
* Fixed cases where Bluez doesn't provide service names for given
Bluetooth service class uuid.
- QBLuetoothSocket:
* [QTBUG-32704] Fixed behavior of isReadable()/isOpen()/isWritable().
So far, these functions returned wrong values.
- QBluetoothTransferReply:
* QBluetoothTransferReply::error() signal added.
* QBluetoothTransferReply::SessionError value added to TransferError enum.
* QBluetoothTransferReply::TransferError enum declared as as meta type.
* Fixed a memory leak on Bluez and QNX.
* Fixed segmentation fault if passed QIODevice was 0.
- QBluetoothUuid:
* Added QBluetoothUuid::protocolToString(QBluetoothUuid::ProtocolUuid)
which returns a human-readable string for the given protocol uuid.
* Various Bluetooth Low Energy related API elements added. This includes
two new constructors, the DescriptorType and CharacteristicType enum,
various values for ServiceClassUuid enum and helper functions to
handle the extended range of new enums.
QtNfc
-----
- General:
* Fixed reference error bug in NFC poster example
****************************************************************************
* Platform Specific Changes *
****************************************************************************
Android
-------
- Fixed broken QBluetoothServer::isListening(). It returned false right
after a successful call to listen().
Bluez/Linux
-----------
- API ported to Bluez 5.x.
- Fixed license issue.
- QBluetoothDeviceDiscoveryAgent:
* Add support to enable detection of Bluetooth Low Energy devices.
- QBluetoothSocket:
* Fixed case where port L2CP port number was not converted to little-endian.
This bug affected big-endian platforms.
......@@ -141,10 +141,11 @@ Rectangle {
id: menu
anchors.bottom: parent.bottom
menuWidth: parent.width
menuText: "Scanning"
menuText: device.update
menuHeight: (parent.height/6)
onButtonClick: {
pageLoader.source = "Services.qml"
device.update = "Back"
}
}
}
......@@ -76,10 +76,6 @@ Rectangle {
else
info.visible = false;
}
onDisconnected: {
pageLoader.source = "main.qml"
}
}
ListView {
......@@ -137,10 +133,12 @@ Rectangle {
id: menu
anchors.bottom: parent.bottom
menuWidth: parent.width
menuText: "Back"
menuText: device.update
menuHeight: (parent.height/6)
onButtonClick: {
device.disconnectFromDevice()
pageLoader.source = "main.qml"
device.update = "Search"
}
}
}
......@@ -155,7 +155,7 @@ void Device::scanServices(const QString &address)
m_services.clear();
emit servicesUpdated();
setUpdate("Connecting to device...");
setUpdate("Back\n(Connecting to device...)");
if (controller && controller->remoteAddress() != currentDevice.getDevice().address()) {
controller->disconnectFromDevice();
......@@ -205,7 +205,7 @@ void Device::addLowEnergyService(const QBluetoothUuid &serviceUuid)
void Device::serviceScanDone()
{
setUpdate("Service scan done!");
setUpdate("Back\n(Service scan done!)");
// force UI in case we didn't find anything
if (m_services.isEmpty())
emit servicesUpdated();
......@@ -234,6 +234,7 @@ void Device::connectToService(const QString &uuid)
connect(service, SIGNAL(stateChanged(QLowEnergyService::ServiceState)),
this, SLOT(serviceDetailsDiscovered(QLowEnergyService::ServiceState)));
service->discoverDetails();
setUpdate("Back\n(Discovering details...)");
//! [les-service-3]
return;
}
......@@ -250,7 +251,7 @@ void Device::connectToService(const QString &uuid)
void Device::deviceConnected()
{
setUpdate("Discovering services!");
setUpdate("Back\n(Discovering services...)");
connected = true;
//! [les-service-2]
controller->discoverServices();
......
......@@ -63,7 +63,7 @@ class Device: public QObject
Q_PROPERTY(QVariant devicesList READ getDevices NOTIFY devicesUpdated)
Q_PROPERTY(QVariant servicesList READ getServices NOTIFY servicesUpdated)
Q_PROPERTY(QVariant characteristicList READ getCharacteristics NOTIFY characteristicsUpdated)
Q_PROPERTY(QString update READ getUpdate NOTIFY updateChanged)
Q_PROPERTY(QString update READ getUpdate WRITE setUpdate NOTIFY updateChanged)
Q_PROPERTY(bool useRandomAddress READ isRandomAddress WRITE setRandomAddress NOTIFY randomAddressChanged)
Q_PROPERTY(bool state READ state NOTIFY stateChanged)
Q_PROPERTY(bool controllerError READ hasControllerError)
......
......@@ -60,6 +60,8 @@ Item {
console.log("Error: Bluetooth device not turned on"); break;
case BluetoothDiscoveryModel.InputOutputError:
console.log("Error: Bluetooth I/O Error"); break;
case BluetoothDiscoveryModel.InvalidBluetoothAdapterError:
console.log("Error: Invalid Bluetooth Adapter Error"); break;
case BluetoothDiscoveryModel.NoError:
break;
default:
......
......@@ -150,6 +150,7 @@ bool HciManager::monitorEvent(HciManager::HciEvent event)
return false;
// this event is already enabled
// TODO runningEvents does not seem to be used
if (runningEvents.contains(event))
return true;
......
......@@ -72,6 +72,7 @@ namespace QBluetooth {
/*!
\typedef QLowEnergyHandle
\relates QBluetooth
\since 5.4
Typedef for Bluetooth Low Energy ATT attribute handles.
*/
......
......@@ -91,7 +91,8 @@ QT_BEGIN_NAMESPACE
\value PoweredOffError The Bluetooth adaptor is powered off, power it on before doing discovery.
\value InputOutputError Writing or reading from the device resulted in an error.
\value InvalidBluetoothAdapterError The passed local adapter address does not match the physical
adapter address of any local Bluetooth device.
adapter address of any local Bluetooth device. This value
was introduced by Qt 5.3.
\value UnknownError An unknown error has occurred.
*/
......
......@@ -48,19 +48,20 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(
const QBluetoothAddress &deviceAdapter)
const QBluetoothAddress &/*deviceAdapter*/)
: error(QBluetoothServiceDiscoveryAgent::NoError),
state(Inactive), deviceDiscoveryAgent(0),
mode(QBluetoothServiceDiscoveryAgent::MinimalDiscovery),
singleDevice(false), receiver(0), localDeviceReceiver(0)
{
QList<QBluetoothHostInfo> devices = QBluetoothLocalDevice::allDevices();
Q_ASSERT(devices.count() == 1); //Android only supports one device at the moment
Q_ASSERT(devices.count() <= 1); //Android only supports one device at the moment
if (deviceAdapter.isNull() && devices.count() > 0 )
m_deviceAdapterAddress = devices.at(0).address();
else
m_deviceAdapterAddress = deviceAdapter;
if (devices.isEmpty()) {
error = QBluetoothServiceDiscoveryAgent::InvalidBluetoothAdapterError;
errorString = QBluetoothServiceDiscoveryAgent::tr("Invalid Bluetooth adapter address");
return;
}
if (QtAndroidPrivate::androidSdkVersion() < 15)
qCWarning(QT_BT_ANDROID)
......@@ -69,13 +70,10 @@ QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(
<< "Service discovery will return empty list.";
/* We assume that the current local adapter has been passed.
Android only supports one adapter at the moment. If m_deviceAdapterAddress
doesn't match the local adapter then we won't get to this point since
we have an InvalidBluetoothAdapter error.
The logic below must change once there is more than one adapter.
*/
/*
We assume that the current local adapter has been passed.
The logic below must change once there is more than one adapter.
*/
btAdapter = QAndroidJniObject::callStaticObjectMethod("android/bluetooth/BluetoothAdapter",
"getDefaultAdapter",
......
......@@ -64,7 +64,8 @@ QT_BEGIN_NAMESPACE
\value UserCanceledTransferError User terminated the transfer.
\value IODeviceNotReadableError File was not open before initiating the sending command.
\value ResourceBusyError Unable to access the resource..
\value SessionError An error occurred during the handling of the session.
\value SessionError An error occurred during the handling of the session. This enum was
introduced by Qt 5.4.
*/
......
......@@ -99,7 +99,8 @@ Q_GLOBAL_STATIC_WITH_ARGS(QUuid, baseUuid, ("{00000000-0000-1000-8000-00805F9B34
it can be used as a value for either of the above service attributes. Such a dual use has historical reasons
but is no longer permissible for newer UUIDs.
The list below explicitly states as what type each UUID shall be used.
The list below explicitly states as what type each UUID shall be used. Bluetooth Low Energy related values
starting with 0x18 were introduced by Qt 5.4
\value ServiceDiscoveryServer Service discovery server UUID (service)
\value BrowseGroupDescriptor Browser group descriptor (service)
......@@ -214,6 +215,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QUuid, baseUuid, ("{00000000-0000-1000-8000-00805F9B34
/*!
\enum QBluetoothUuid::CharacteristicType
\since 5.4
This enum is a convienience type for Bluetooth low energy service characteristics class UUIDs. Values of this type
will be implicitly converted into a QBluetoothUuid when necessary.
......@@ -369,6 +371,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QUuid, baseUuid, ("{00000000-0000-1000-8000-00805F9B34
/*!
\enum QBluetoothUuid::DescriptorType
\since 5.4
Descriptors are attributes that describe Bluetooth Low Energy characteristic values.
......@@ -425,6 +428,7 @@ QBluetoothUuid::QBluetoothUuid(ServiceClassUuid uuid)
/*!
Constructs a new Bluetooth UUID from the characteristic type \a uuid.
\since 5.4
*/
QBluetoothUuid::QBluetoothUuid(CharacteristicType uuid)
: QUuid(uuid, baseUuid()->data2, baseUuid()->data3, baseUuid()->data4[0], baseUuid()->data4[1],
......@@ -435,6 +439,7 @@ QBluetoothUuid::QBluetoothUuid(CharacteristicType uuid)
/*!
Constructs a new Bluetooth UUID from the descriptor type \a uuid.
\since 5.4
*/
QBluetoothUuid::QBluetoothUuid(DescriptorType uuid)
: QUuid(uuid, baseUuid()->data2, baseUuid()->data3, baseUuid()->data4[0], baseUuid()->data4[1],
......
......@@ -271,6 +271,7 @@ void QLowEnergyControllerPrivate::disconnectFromDevice()
{
setState(QLowEnergyController::ClosingState);
l2cpSocket->close();
resetController();
}
void QLowEnergyControllerPrivate::l2cpDisconnected()
......@@ -306,9 +307,19 @@ void QLowEnergyControllerPrivate::l2cpErrorChanged(QBluetoothSocket::SocketError
}
invalidateServices();
resetController();
setState(QLowEnergyController::UnconnectedState);
}
void QLowEnergyControllerPrivate::resetController()
{
openRequests.clear();
requestPending = false;
encryptionChangePending = false;
securityLevelValue = -1;
}
void QLowEnergyControllerPrivate::l2cpReadyRead()
{
const QByteArray reply = l2cpSocket->readAll();
......
......@@ -160,6 +160,8 @@ private:
const QByteArray &newValue, quint16 offset);
bool increaseEncryptLevelfRequired(quint8 errorCode);
void resetController();
private slots:
void l2cpConnected();
void l2cpDisconnected();
......
......@@ -149,6 +149,9 @@ QT_BEGIN_NAMESPACE
to be a secondary service. Each service may be included
by another service which is indicated by IncludedService.
\value IncludedService The service is included by another service.
On some platforms, this flag cannot be determined until
the service that includes the current service was
discovered.
*/
/*!
......@@ -306,6 +309,9 @@ QLowEnergyService::~QLowEnergyService()
Returns the UUIDs of all services which are included by the
current service.
The returned list is empty if this service instance's \l discoverDetails()
was not yet called or there are no known characteristics.
It is possible that an included service contains yet another service. Such
second level includes have to be obtained via their relevant first level
QLowEnergyService instance. Technically, this could create
......@@ -331,7 +337,6 @@ QList<QBluetoothUuid> QLowEnergyService::includedServices() const
Therefore any service object instance created after
the first one has a state equal to already existing instances.
A service becomes invalid if the \l QLowEnergyController disconnects
from the remote device. An invalid service retains its internal state
at the time of the disconnect event. This implies that once the service
......@@ -353,6 +358,11 @@ QLowEnergyService::ServiceState QLowEnergyService::state() const
/*!
Returns the type of the service.
\note The type attribute cannot be relied upon until the service has
reached the \l ServiceDiscovered state. This field is initialised
with \l PrimaryService.
*/
QLowEnergyService::ServiceTypes QLowEnergyService::type() const
{
......@@ -363,6 +373,9 @@ QLowEnergyService::ServiceTypes QLowEnergyService::type() const
Returns the matching characteristic for \a uuid; otherwise an invalid
characteristic.
The returned characteristic is invalid if this service instance's \l discoverDetails()
was not yet called or there are no characteristics with a matching \a uuid.
\sa characteristics()
*/
QLowEnergyCharacteristic QLowEnergyService::characteristic(const QBluetoothUuid &uuid) const
......
......@@ -30,7 +30,8 @@ Module {
"NoError": 0,
"InputOutputError": 1,
"PoweredOffError": 2,
"UnknownError": 3
"UnknownError": 3,
"InvalidBluetoothAdapterError": 4
}
}
Property { name: "error"; type: "Error"; isReadonly: true }
......
......@@ -151,7 +151,19 @@ void QDeclarativeBluetoothDiscoveryModel::componentComplete()
void QDeclarativeBluetoothDiscoveryModel::errorDiscovery(QBluetoothServiceDiscoveryAgent::Error error)
{
d->m_error = static_cast<QDeclarativeBluetoothDiscoveryModel::Error>(error);
switch (error) {
case QBluetoothServiceDiscoveryAgent::InvalidBluetoothAdapterError:
d->m_error = QDeclarativeBluetoothDiscoveryModel::InvalidBluetoothAdapterError; break;
case QBluetoothServiceDiscoveryAgent::NoError:
d->m_error = QDeclarativeBluetoothDiscoveryModel::NoError; break;
case QBluetoothServiceDiscoveryAgent::InputOutputError:
d->m_error = QDeclarativeBluetoothDiscoveryModel::InputOutputError; break;
case QBluetoothServiceDiscoveryAgent::PoweredOffError:
d->m_error = QDeclarativeBluetoothDiscoveryModel::PoweredOffError; break;
case QBluetoothServiceDiscoveryAgent::UnknownError:
d->m_error = QDeclarativeBluetoothDiscoveryModel::UnknownError; break;
}
emit errorChanged();
}
......@@ -187,6 +199,12 @@ void QDeclarativeBluetoothDiscoveryModel::clearModel()
\li An IO failure occurred during device discovery
\row \li \c BluetoothDiscoveryModel.PoweredOffError
\li The bluetooth device is not powered on.
\row \li \c BluetoothDiscoveryModel.InvalidBluetoothAdapterError
\li There is no default Bluetooth device to perform the
service discovery. The model always uses the local default adapter.
Specifying a default adapter is not possible. If that's required,
\l QBluetoothServiceDiscoveryAgent should be directly used. This
value was introduced by Qt 5.4.
\row \li \c BluetoothDiscoveryModel.UnknownError
\li An unknown error occurred.
\endtable
......@@ -407,6 +425,13 @@ void QDeclarativeBluetoothDiscoveryModel::setRunning(bool running)
//qDebug() << "Minimal Discovery";
d->m_serviceAgent->start(QBluetoothServiceDiscoveryAgent::MinimalDiscovery);
}
// we could not start service discovery
if (!d->m_serviceAgent->isActive()) {
d->m_running = false;
errorDiscovery(d->m_serviceAgent->error());
return;
}
}
}
......
......@@ -94,7 +94,8 @@ public:
NoError,
InputOutputError,
PoweredOffError,
UnknownError
UnknownError,
InvalidBluetoothAdapterError
};
Error error() const;
......