diff options
author | Michael Zanetti <michael.zanetti@nokia.com> | 2011-08-24 14:09:22 +1000 |
---|---|---|
committer | Rohan McGovern <rohan.mcgovern@nokia.com> | 2011-08-24 14:10:36 +1000 |
commit | 29ba8297443cf76d4f647bde329d62c2a567c709 (patch) | |
tree | 88875199053cd88b3b3521c829277f209e815159 /src/bluetooth |
Initial commit.
From qt5connectivity.tar.gz, md5 317c149d6f8c07d09632353188582834
Diffstat (limited to 'src/bluetooth')
112 files changed, 17046 insertions, 0 deletions
diff --git a/src/bluetooth/bluetooth.pro b/src/bluetooth/bluetooth.pro new file mode 100644 index 00000000..f1b00b30 --- /dev/null +++ b/src/bluetooth/bluetooth.pro @@ -0,0 +1,162 @@ +load(qt_module) + +TARGET = QtBluetooth +QPRO_PWD = $PWD + +CONFIG += module +MODULE_PRI = ../../modules/qt_bluetooth.pri + +DEFINES += QT_BUILD_BT_LIB QT_MAKEDLL + +load(qt_module_config) + +PUBLIC_HEADERS += \ + qbluetoothaddress.h\ + qbluetoothuuid.h\ + qbluetoothdeviceinfo.h\ + qbluetoothserviceinfo.h\ + qbluetoothdevicediscoveryagent.h\ + qbluetoothservicediscoveryagent.h\ + qbluetoothsocket.h\ + qrfcommserver.h \ + ql2capserver.h \ + qbluetooth.h \ + qbluetoothlocaldevice.h \ + ql2capsocket.h \ + qrfcommsocket.h \ + qbluetoothtransfermanager.h \ + qbluetoothtransferrequest.h \ + qbluetoothtransferreply.h + +PRIVATE_HEADERS += \ + qbluetoothaddress_p.h\ + qbluetoothdeviceinfo_p.h\ + qbluetoothserviceinfo_p.h\ + qbluetoothdevicediscoveryagent_p.h\ + qbluetoothservicediscoveryagent_p.h\ + qbluetoothsocket_p.h\ + qrfcommserver_p.h \ + ql2capserver_p.h \ + qbluetoothtransferreply_p.h \ + qbluetoothtransferrequest_p.h + +SOURCES += \ + qbluetoothaddress.cpp\ + qbluetoothuuid.cpp\ + qbluetoothdeviceinfo.cpp\ + qbluetoothserviceinfo.cpp\ + qbluetoothdevicediscoveryagent.cpp\ + qbluetoothservicediscoveryagent.cpp\ + qbluetoothsocket.cpp\ + qrfcommserver.cpp \ + ql2capserver.cpp \ + qbluetoothlocaldevice.cpp \ + qbluetooth.cpp \ + ql2capsocket.cpp \ + qrfcommsocket.cpp \ + qbluetoothtransfermanager.cpp \ + qbluetoothtransferrequest.cpp \ + qbluetoothtransferreply.cpp + +symbian { + contains(S60_VERSION, 3.1) | contains(S60_VERSION, 3.2) { + DEFINES += DO_NOT_BUILD_BLUETOOTH_SYMBIAN_BACKEND + message("S60 3.1 or 3.2 sdk not supported by bluetooth") + SOURCES += \ + qbluetoothdevicediscoveryagent_p.cpp \ + qbluetoothlocaldevice_p.cpp \ + qbluetoothserviceinfo_p.cpp \ + qbluetoothservicediscoveryagent_p.cpp \ + qbluetoothsocket_p.cpp \ + ql2capserver_p.cpp \ + qrfcommserver_p.cpp \ + qbluetoothtransfermanager_p.cpp + } +} + +symbian { + !contains(DEFINES, DO_NOT_BUILD_BLUETOOTH_SYMBIAN_BACKEND) { + DEFINES += QT_SYMBIAN_BLUETOOTH + INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE + include(symbian/symbian.pri) + + PRIVATE_HEADERS += \ + qbluetoothtransferreply_symbian_p.h \ + qbluetoothlocaldevice_p.h + + SOURCES += \ + qbluetoothserviceinfo_symbian.cpp\ + qbluetoothdevicediscoveryagent_symbian.cpp\ + qbluetoothservicediscoveryagent_symbian.cpp\ + qbluetoothsocket_symbian.cpp\ + qrfcommserver_symbian.cpp \ + qbluetoothlocaldevice_symbian.cpp \ + qbluetoothtransfermanager_symbian.cpp \ + qbluetoothtransferreply_symbian.cpp \ + ql2capserver_symbian.cpp + + contains(S60_VERSION, 5.0) { + message("NOTICE - START") + message("Bluetooth backend needs SDK plugin from Forum Nokia for 5.0 SDK") + message("NOTICE - END") + LIBS *= -lirobex + } else { + LIBS *= -lobex + } + LIBS *= -lesock \ + -lbluetooth \ + -lsdpagent \ + -lsdpdatabase \ + -lestlib \ + -lbtengsettings \ + -lbtmanclient \ + -lbtdevice + } +} else:contains(config_test_bluez, yes):contains(QT_CONFIG, dbus) { + QT *= dbus + DEFINES += QT_BLUEZ_BLUETOOTH + + include(bluez/bluez.pri) + + PRIVATE_HEADERS += \ + qbluetoothtransferreply_bluez_p.h \ + qbluetoothlocaldevice_p.h + + SOURCES += \ + qbluetoothserviceinfo_bluez.cpp \ + qbluetoothdevicediscoveryagent_bluez.cpp\ + qbluetoothservicediscoveryagent_bluez.cpp \ + qbluetoothsocket_bluez.cpp \ + qrfcommserver_bluez.cpp \ + qbluetoothlocaldevice_bluez.cpp \ + qbluetoothtransferreply_bluez.cpp \ + qbluetoothtransfermanager_bluez.cpp \ + ql2capserver_bluez.cpp + + exists(/usr/include/test_framework_4711.h) { + message(Activating Nokia Bluetooth Services) + DEFINES += NOKIA_BT_SERVICES + QT += serviceframework + } + +} else { + message("Unsupported bluetooth platform, will not build a working QBluetooth library") + message("Either no Qt dBus found, no bluez headers, or not symbian") + SOURCES += \ + qbluetoothdevicediscoveryagent_p.cpp \ + qbluetoothlocaldevice_p.cpp \ + qbluetoothserviceinfo_p.cpp \ + qbluetoothservicediscoveryagent_p.cpp \ + qbluetoothsocket_p.cpp \ + ql2capserver_p.cpp \ + qrfcommserver_p.cpp \ + qbluetoothtransfermanager_p.cpp + +} + +INCLUDEPATH += $$PWD +INCLUDEPATH += .. + +OTHER_FILES += + +HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS diff --git a/src/bluetooth/bluez/adapter.cpp b/src/bluetooth/bluez/adapter.cpp new file mode 100644 index 00000000..495360d7 --- /dev/null +++ b/src/bluetooth/bluez/adapter.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -p adapter_p.h:adapter.cpp org.bluez.all.xml org.bluez.Adapter + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "adapter_p.h" + +/* + * Implementation of interface class OrgBluezAdapterInterface + */ + +OrgBluezAdapterInterface::OrgBluezAdapterInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +OrgBluezAdapterInterface::~OrgBluezAdapterInterface() +{ +} + diff --git a/src/bluetooth/bluez/adapter_p.h b/src/bluetooth/bluez/adapter_p.h new file mode 100644 index 00000000..b4ba2b12 --- /dev/null +++ b/src/bluetooth/bluez/adapter_p.h @@ -0,0 +1,157 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -p adapter_p.h:adapter.cpp org.bluez.all.xml org.bluez.Adapter + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef ADAPTER_P_H_1273205927 +#define ADAPTER_P_H_1273205927 + +#include <QtCore/QObject> +#include <QtCore/QByteArray> +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QVariant> +#include <QtDBus/QtDBus> + +/* + * Proxy class for interface org.bluez.Adapter + */ +class OrgBluezAdapterInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "org.bluez.Adapter"; } + +public: + OrgBluezAdapterInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~OrgBluezAdapterInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> CancelDeviceCreation(const QString &in0) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0); + return asyncCallWithArgumentList(QLatin1String("CancelDeviceCreation"), argumentList); + } + + inline QDBusPendingReply<QDBusObjectPath> CreateDevice(const QString &in0) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0); + return asyncCallWithArgumentList(QLatin1String("CreateDevice"), argumentList); + } + + inline QDBusPendingReply<QDBusObjectPath> CreatePairedDevice(const QString &in0, const QDBusObjectPath &in1, const QString &in2) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0) << qVariantFromValue(in1) << qVariantFromValue(in2); + return asyncCallWithArgumentList(QLatin1String("CreatePairedDevice"), argumentList); + } + + inline QDBusPendingReply<QDBusObjectPath> FindDevice(const QString &in0) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0); + return asyncCallWithArgumentList(QLatin1String("FindDevice"), argumentList); + } + + inline QDBusPendingReply<QVariantMap> GetProperties() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList); + } + + inline QDBusPendingReply<QList<QDBusObjectPath> > ListDevices() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("ListDevices"), argumentList); + } + + inline QDBusPendingReply<> RegisterAgent(const QDBusObjectPath &in0, const QString &in1) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0) << qVariantFromValue(in1); + return asyncCallWithArgumentList(QLatin1String("RegisterAgent"), argumentList); + } + + inline QDBusPendingReply<> ReleaseMode() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("ReleaseMode"), argumentList); + } + + inline QDBusPendingReply<> ReleaseSession() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("ReleaseSession"), argumentList); + } + + inline QDBusPendingReply<> RemoveDevice(const QDBusObjectPath &in0) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0); + return asyncCallWithArgumentList(QLatin1String("RemoveDevice"), argumentList); + } + + inline QDBusPendingReply<> RequestMode(const QString &in0) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0); + return asyncCallWithArgumentList(QLatin1String("RequestMode"), argumentList); + } + + inline QDBusPendingReply<> RequestSession() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("RequestSession"), argumentList); + } + + inline QDBusPendingReply<> SetProperty(const QString &in0, const QDBusVariant &in1) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0) << qVariantFromValue(in1); + return asyncCallWithArgumentList(QLatin1String("SetProperty"), argumentList); + } + + inline QDBusPendingReply<> StartDiscovery() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("StartDiscovery"), argumentList); + } + + inline QDBusPendingReply<> StopDiscovery() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("StopDiscovery"), argumentList); + } + + inline QDBusPendingReply<> UnregisterAgent(const QDBusObjectPath &in0) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0); + return asyncCallWithArgumentList(QLatin1String("UnregisterAgent"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void DeviceCreated(const QDBusObjectPath &in0); + void DeviceDisappeared(const QString &in0); + void DeviceFound(const QString &in0, const QVariantMap &in1); + void DeviceRemoved(const QDBusObjectPath &in0); + void PropertyChanged(const QString &in0, const QDBusVariant &in1); +}; + +namespace org { + namespace bluez { + typedef ::OrgBluezAdapterInterface Adapter; + } +} +#endif diff --git a/src/bluetooth/bluez/agent.cpp b/src/bluetooth/bluez/agent.cpp new file mode 100644 index 00000000..491bd1e9 --- /dev/null +++ b/src/bluetooth/bluez/agent.cpp @@ -0,0 +1,87 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c OrgBluezAgentAdaptor -a agent_p.h:agent.cpp org.bluez.Agent.xml org.bluez.Agent + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "agent_p.h" +#include <QtCore/QMetaObject> +#include <QtCore/QByteArray> +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QVariant> + +/* + * Implementation of adaptor class OrgBluezAgentAdaptor + */ + +OrgBluezAgentAdaptor::OrgBluezAgentAdaptor(QObject *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +OrgBluezAgentAdaptor::~OrgBluezAgentAdaptor() +{ + // destructor +} + +void OrgBluezAgentAdaptor::Authorize(const QDBusObjectPath &in0, const QString &in1) +{ + // handle method call org.bluez.Agent.Authorize + QMetaObject::invokeMethod(parent(), "Authorize", Q_ARG(QDBusObjectPath, in0), Q_ARG(QString, in1)); +} + +void OrgBluezAgentAdaptor::Cancel() +{ + // handle method call org.bluez.Agent.Cancel + QMetaObject::invokeMethod(parent(), "Cancel"); +} + +void OrgBluezAgentAdaptor::ConfirmModeChange(const QString &in0) +{ + // handle method call org.bluez.Agent.ConfirmModeChange + QMetaObject::invokeMethod(parent(), "ConfirmModeChange", Q_ARG(QString, in0)); +} + +void OrgBluezAgentAdaptor::DisplayPasskey(const QDBusObjectPath &in0, uint in1, uchar in2) +{ + // handle method call org.bluez.Agent.DisplayPasskey + QMetaObject::invokeMethod(parent(), "DisplayPasskey", Q_ARG(QDBusObjectPath, in0), Q_ARG(uint, in1), Q_ARG(uchar, in2)); +} + +void OrgBluezAgentAdaptor::Release() +{ + // handle method call org.bluez.Agent.Release + QMetaObject::invokeMethod(parent(), "Release"); +} + +void OrgBluezAgentAdaptor::RequestConfirmation(const QDBusObjectPath &in0, uint in1) +{ + // handle method call org.bluez.Agent.RequestConfirmation + QMetaObject::invokeMethod(parent(), "RequestConfirmation", Q_ARG(QDBusObjectPath, in0), Q_ARG(uint, in1)); +} + +uint OrgBluezAgentAdaptor::RequestPasskey(const QDBusObjectPath &in0) +{ + // handle method call org.bluez.Agent.RequestPasskey + uint out0; + QMetaObject::invokeMethod(parent(), "RequestPasskey", Q_RETURN_ARG(uint, out0), Q_ARG(QDBusObjectPath, in0)); + return out0; +} + +QString OrgBluezAgentAdaptor::RequestPinCode(const QDBusObjectPath &in0) +{ + // handle method call org.bluez.Agent.RequestPinCode + QString out0; + QMetaObject::invokeMethod(parent(), "RequestPinCode", Q_RETURN_ARG(QString, out0), Q_ARG(QDBusObjectPath, in0)); + return out0; +} + diff --git a/src/bluetooth/bluez/agent_p.h b/src/bluetooth/bluez/agent_p.h new file mode 100644 index 00000000..3725928e --- /dev/null +++ b/src/bluetooth/bluez/agent_p.h @@ -0,0 +1,78 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -c OrgBluezAgentAdaptor -a agent_p.h:agent.cpp org.bluez.Agent.xml org.bluez.Agent + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef AGENT_P_H_1291941396 +#define AGENT_P_H_1291941396 + +#include <QtCore/QObject> +#include <QtDBus/QtDBus> +class QByteArray; +template<class T> class QList; +template<class Key, class Value> class QMap; +class QString; +class QStringList; +class QVariant; + +/* + * Adaptor class for interface org.bluez.Agent + */ +class OrgBluezAgentAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.bluez.Agent") + Q_CLASSINFO("D-Bus Introspection", "" +" <interface name=\"org.bluez.Agent\">\n" +" <method name=\"Release\"/>\n" +" <method name=\"RequestPinCode\">\n" +" <arg direction=\"in\" type=\"o\"/>\n" +" <arg direction=\"out\" type=\"s\"/>\n" +" </method>\n" +" <method name=\"RequestPasskey\">\n" +" <arg direction=\"in\" type=\"o\"/>\n" +" <arg direction=\"out\" type=\"u\"/>\n" +" </method>\n" +" <method name=\"DisplayPasskey\">\n" +" <arg direction=\"in\" type=\"o\"/>\n" +" <arg direction=\"in\" type=\"u\"/>\n" +" <arg direction=\"in\" type=\"y\"/>\n" +" </method>\n" +" <method name=\"RequestConfirmation\">\n" +" <arg direction=\"in\" type=\"o\"/>\n" +" <arg direction=\"in\" type=\"u\"/>\n" +" </method>\n" +" <method name=\"Authorize\">\n" +" <arg direction=\"in\" type=\"o\"/>\n" +" <arg direction=\"in\" type=\"s\"/>\n" +" </method>\n" +" <method name=\"ConfirmModeChange\">\n" +" <arg direction=\"in\" type=\"s\"/>\n" +" </method>\n" +" <method name=\"Cancel\"/>\n" +" </interface>\n" + "") +public: + OrgBluezAgentAdaptor(QObject *parent); + virtual ~OrgBluezAgentAdaptor(); + +public: // PROPERTIES +public Q_SLOTS: // METHODS + void Authorize(const QDBusObjectPath &in0, const QString &in1); + void Cancel(); + void ConfirmModeChange(const QString &in0); + void DisplayPasskey(const QDBusObjectPath &in0, uint in1, uchar in2); + void Release(); + void RequestConfirmation(const QDBusObjectPath &in0, uint in1); + uint RequestPasskey(const QDBusObjectPath &in0); + QString RequestPinCode(const QDBusObjectPath &in0); +Q_SIGNALS: // SIGNALS +}; + +#endif diff --git a/src/bluetooth/bluez/bluez.pri b/src/bluetooth/bluez/bluez.pri new file mode 100644 index 00000000..234b5ba2 --- /dev/null +++ b/src/bluetooth/bluez/bluez.pri @@ -0,0 +1,23 @@ + +HEADERS += bluez/manager_p.h \ + bluez/adapter_p.h \ + bluez/device_p.h \ + bluez/service_p.h \ + bluez/agent_p.h \ + bluez/servicemap_p.h \ + bluez/obex_client_p.h \ + bluez/obex_agent_p.h \ + bluez/obex_transfer_p.h \ + bluez/obex_manager_p.h + + +SOURCES += bluez/manager.cpp \ + bluez/adapter.cpp \ + bluez/agent.cpp \ + bluez/device.cpp \ + bluez/service.cpp \ + bluez/servicemap.cpp \ + bluez/obex_client.cpp \ + bluez/obex_agent.cpp \ + bluez/obex_transfer.cpp \ + bluez/obex_manager.cpp diff --git a/src/bluetooth/bluez/device.cpp b/src/bluetooth/bluez/device.cpp new file mode 100644 index 00000000..fa3f7c44 --- /dev/null +++ b/src/bluetooth/bluez/device.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -i servicemap_p.h -p device_p.h:device.cpp org.bluez.Device.xml org.bluez.Device + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "device_p.h" + +/* + * Implementation of interface class OrgBluezDeviceInterface + */ + +OrgBluezDeviceInterface::OrgBluezDeviceInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +OrgBluezDeviceInterface::~OrgBluezDeviceInterface() +{ +} + diff --git a/src/bluetooth/bluez/device_p.h b/src/bluetooth/bluez/device_p.h new file mode 100644 index 00000000..26a00828 --- /dev/null +++ b/src/bluetooth/bluez/device_p.h @@ -0,0 +1,104 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -i servicemap_p.h -p device_p.h:device.cpp org.bluez.Device.xml org.bluez.Device + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef DEVICE_P_H_1273205927 +#define DEVICE_P_H_1273205927 + +#include <QtCore/QObject> +#include <QtCore/QByteArray> +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QVariant> +#include <QtDBus/QtDBus> +#include "servicemap_p.h" + +/* + * Proxy class for interface org.bluez.Device + */ +class OrgBluezDeviceInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "org.bluez.Device"; } + +public: + OrgBluezDeviceInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~OrgBluezDeviceInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> CancelDiscovery() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("CancelDiscovery"), argumentList); + } + + inline QDBusPendingReply<QDBusObjectPath> CreateNode(const QString &in0) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0); + return asyncCallWithArgumentList(QLatin1String("CreateNode"), argumentList); + } + + inline QDBusPendingReply<> Disconnect() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("Disconnect"), argumentList); + } + + inline QDBusPendingReply<ServiceMap> DiscoverServices(const QString &in0) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0); + return asyncCallWithArgumentList(QLatin1String("DiscoverServices"), argumentList); + } + + inline QDBusPendingReply<QVariantMap> GetProperties() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList); + } + + inline QDBusPendingReply<QList<QDBusObjectPath> > ListNodes() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("ListNodes"), argumentList); + } + + inline QDBusPendingReply<> RemoveNode(const QDBusObjectPath &in0) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0); + return asyncCallWithArgumentList(QLatin1String("RemoveNode"), argumentList); + } + + inline QDBusPendingReply<> SetProperty(const QString &in0, const QDBusVariant &in1) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0) << qVariantFromValue(in1); + return asyncCallWithArgumentList(QLatin1String("SetProperty"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void DisconnectRequested(); + void NodeCreated(const QDBusObjectPath &in0); + void NodeRemoved(const QDBusObjectPath &in0); + void PropertyChanged(const QString &in0, const QDBusVariant &in1); +}; + +namespace org { + namespace bluez { + typedef ::OrgBluezDeviceInterface Device; + } +} +#endif diff --git a/src/bluetooth/bluez/generate b/src/bluetooth/bluez/generate new file mode 100755 index 00000000..14bcaea8 --- /dev/null +++ b/src/bluetooth/bluez/generate @@ -0,0 +1,16 @@ +#!/bin/sh + +qdbusxml2cpp -p manager_p.h:manager.cpp org.bluez.Manager.xml org.bluez.Manager +qdbusxml2cpp -p adapter_p.h:adapter.cpp org.bluez.all.xml org.bluez.Adapter +qdbusxml2cpp -i servicemap_p.h -p device_p.h:device.cpp org.bluez.Device.xml org.bluez.Device +qdbusxml2cpp -p service_p.h:service.cpp org.bluez.all.xml org.bluez.Service +qdbusxml2cpp -c OrgBluezAgentAdaptor -a agent_p.h:agent.cpp org.bluez.Agent.xml org.bluez.Agent +qdbusxml2cpp -p obex_manager_p.h:obex_manager.cpp org.openobex.all.xml org.openobex.Manager +qdbusxml2cpp -p obex_client_p.h:obex_client.cpp org.openobex.client.xml org.openobex.Client +qdbusxml2cpp -p obex_transfer_p.h:obex_transfer.cpp org.openobex.transfer.xml org.openobex.Transfer +qdbusxml2cpp -a obex_agent_p.h:obex_agent.cpp org.openobex.agent.xml org.openobex.Agent +#qdbusxml2cpp -p serialproxymanager_p.h:serialproxymanager.cpp org.bluez.all.xml org.bluez.SerialProxyManager +#qdbusxml2cpp -p networkpeer_p.h:networkpeer.cpp org.bluez.all.xml org.bluez.NetworkPeer +#qdbusxml2cpp -p networkhub_p.h:networkhub.cpp org.bluez.all.xml org.bluez.NetworkHub +#qdbusxml2cpp -p networkrouter_p.h:networkrouter.cpp org.bluez.all.xml org.bluez.NetworkRouter + diff --git a/src/bluetooth/bluez/manager.cpp b/src/bluetooth/bluez/manager.cpp new file mode 100644 index 00000000..474ed694 --- /dev/null +++ b/src/bluetooth/bluez/manager.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -p manager_p.h:manager.cpp org.bluez.Manager.xml org.bluez.Manager + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "manager_p.h" + +/* + * Implementation of interface class OrgBluezManagerInterface + */ + +OrgBluezManagerInterface::OrgBluezManagerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +OrgBluezManagerInterface::~OrgBluezManagerInterface() +{ +} + diff --git a/src/bluetooth/bluez/manager_p.h b/src/bluetooth/bluez/manager_p.h new file mode 100644 index 00000000..da38f733 --- /dev/null +++ b/src/bluetooth/bluez/manager_p.h @@ -0,0 +1,69 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -p manager_p.h:manager.cpp org.bluez.Manager.xml org.bluez.Manager + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef MANAGER_P_H_1273205927 +#define MANAGER_P_H_1273205927 + +#include <QtCore/QObject> +#include <QtCore/QByteArray> +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QVariant> +#include <QtDBus/QtDBus> + +/* + * Proxy class for interface org.bluez.Manager + */ +class OrgBluezManagerInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "org.bluez.Manager"; } + +public: + OrgBluezManagerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~OrgBluezManagerInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<QDBusObjectPath> DefaultAdapter() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("DefaultAdapter"), argumentList); + } + + inline QDBusPendingReply<QDBusObjectPath> FindAdapter(const QString &in0) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0); + return asyncCallWithArgumentList(QLatin1String("FindAdapter"), argumentList); + } + + inline QDBusPendingReply<QList<QDBusObjectPath> > ListAdapters() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("ListAdapters"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void AdapterAdded(const QDBusObjectPath &in0); + void AdapterRemoved(const QDBusObjectPath &in0); + void DefaultAdapterChanged(const QDBusObjectPath &in0); +}; + +namespace org { + namespace bluez { + typedef ::OrgBluezManagerInterface Manager; + } +} +#endif diff --git a/src/bluetooth/bluez/obex_agent.cpp b/src/bluetooth/bluez/obex_agent.cpp new file mode 100644 index 00000000..c4895065 --- /dev/null +++ b/src/bluetooth/bluez/obex_agent.cpp @@ -0,0 +1,67 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -a obex_agent_p.h:obex_agent.cpp org.openobex.agent.xml + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#include "obex_agent_p.h" +#include <QtCore/QMetaObject> +#include <QtCore/QByteArray> +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QVariant> + +/* + * Implementation of adaptor class AgentAdaptor + */ + +AgentAdaptor::AgentAdaptor(QObject *parent) + : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +AgentAdaptor::~AgentAdaptor() +{ + // destructor +} + +void AgentAdaptor::Complete(const QDBusObjectPath &in0) +{ + // handle method call org.openobex.Agent.Complete + QMetaObject::invokeMethod(parent(), "Complete", Q_ARG(QDBusObjectPath, in0)); +} + +void AgentAdaptor::Error(const QDBusObjectPath &in0, const QString &in1) +{ + // handle method call org.openobex.Agent.Error + QMetaObject::invokeMethod(parent(), "Error", Q_ARG(QDBusObjectPath, in0), Q_ARG(QString, in1)); +} + +void AgentAdaptor::Progress(const QDBusObjectPath &in0, qulonglong in1) +{ + // handle method call org.openobex.Agent.Progress + QMetaObject::invokeMethod(parent(), "Progress", Q_ARG(QDBusObjectPath, in0), Q_ARG(qulonglong, in1)); +} + +void AgentAdaptor::Release() +{ + // handle method call org.openobex.Agent.Release + QMetaObject::invokeMethod(parent(), "Release"); +} + +QString AgentAdaptor::Request(const QDBusObjectPath &in0) +{ + // handle method call org.openobex.Agent.Request + QString out0; + QMetaObject::invokeMethod(parent(), "Request", Q_RETURN_ARG(QString, out0), Q_ARG(QDBusObjectPath, in0)); + return out0; +} + diff --git a/src/bluetooth/bluez/obex_agent_p.h b/src/bluetooth/bluez/obex_agent_p.h new file mode 100644 index 00000000..11630093 --- /dev/null +++ b/src/bluetooth/bluez/obex_agent_p.h @@ -0,0 +1,65 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -a obex_agent_p.h:obex_agent.cpp org.openobex.agent.xml + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef OBEX_AGENT_P_H_1291359033 +#define OBEX_AGENT_P_H_1291359033 + +#include <QtCore/QObject> +#include <QtDBus/QtDBus> +class QByteArray; +template<class T> class QList; +template<class Key, class Value> class QMap; +class QString; +class QStringList; +class QVariant; + +/* + * Adaptor class for interface org.openobex.Agent + */ +class AgentAdaptor: public QDBusAbstractAdaptor +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.openobex.Agent") + Q_CLASSINFO("D-Bus Introspection", "" +" <interface name=\"org.openobex.Agent\">\n" +" <method name=\"Release\"/>\n" +" <method name=\"Request\">\n" +" <arg direction=\"in\" type=\"o\"/>\n" +" <arg direction=\"out\" type=\"s\"/>\n" +" </method>\n" +" <method name=\"Progress\">\n" +" <arg direction=\"in\" type=\"o\"/>\n" +" <arg direction=\"in\" type=\"t\"/>\n" +" </method>\n" +" <method name=\"Complete\">\n" +" <arg direction=\"in\" type=\"o\"/>\n" +" </method>\n" +" <method name=\"Error\">\n" +" <arg direction=\"in\" type=\"o\"/>\n" +" <arg direction=\"in\" type=\"s\"/>\n" +" </method>\n" +" </interface>\n" + "") +public: + AgentAdaptor(QObject *parent); + virtual ~AgentAdaptor(); + +public: // PROPERTIES +public Q_SLOTS: // METHODS + void Complete(const QDBusObjectPath &in0); + void Error(const QDBusObjectPath &in0, const QString &in1); + void Progress(const QDBusObjectPath &in0, qulonglong in1); + void Release(); + QString Request(const QDBusObjectPath &in0); +Q_SIGNALS: // SIGNALS +}; + +#endif diff --git a/src/bluetooth/bluez/obex_client.cpp b/src/bluetooth/bluez/obex_client.cpp new file mode 100644 index 00000000..aaf63532 --- /dev/null +++ b/src/bluetooth/bluez/obex_client.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -p obex_client_p.h:obex_client.cpp org.openobex.client.xml org.openobex.Client + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "obex_client_p.h" + +/* + * Implementation of interface class OrgOpenobexClientInterface + */ + +OrgOpenobexClientInterface::OrgOpenobexClientInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +OrgOpenobexClientInterface::~OrgOpenobexClientInterface() +{ +} + diff --git a/src/bluetooth/bluez/obex_client_p.h b/src/bluetooth/bluez/obex_client_p.h new file mode 100644 index 00000000..fa6b1f67 --- /dev/null +++ b/src/bluetooth/bluez/obex_client_p.h @@ -0,0 +1,82 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -p obex_client_p.h:obex_client.cpp org.openobex.client.xml org.openobex.Client + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef OBEX_CLIENT_P_H_1291349694 +#define OBEX_CLIENT_P_H_1291349694 + +#include <QtCore/QObject> +#include <QtCore/QByteArray> +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QVariant> +#include <QtDBus/QtDBus> + +/* + * Proxy class for interface org.openobex.Client + */ +class OrgOpenobexClientInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "org.openobex.Client"; } + +public: + OrgOpenobexClientInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~OrgOpenobexClientInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<QDBusObjectPath> CreateSession(const QVariantMap &in0) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0); + return asyncCallWithArgumentList(QLatin1String("CreateSession"), argumentList); + } + + inline QDBusPendingReply<> ExchangeBusinessCards(const QVariantMap &in0, const QString &in1, const QString &in2) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0) << qVariantFromValue(in1) << qVariantFromValue(in2); + return asyncCallWithArgumentList(QLatin1String("ExchangeBusinessCards"), argumentList); + } + + inline QDBusPendingReply<QString> GetCapabilities(const QVariantMap &in0) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0); + return asyncCallWithArgumentList(QLatin1String("GetCapabilities"), argumentList); + } + + inline QDBusPendingReply<> PullBusinessCard(const QVariantMap &in0, const QString &in1) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0) << qVariantFromValue(in1); + return asyncCallWithArgumentList(QLatin1String("PullBusinessCard"), argumentList); + } + + inline QDBusPendingReply<> SendFiles(const QVariantMap &in0, const QStringList &in1, const QDBusObjectPath &in2) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0) << qVariantFromValue(in1) << qVariantFromValue(in2); + return asyncCallWithArgumentList(QLatin1String("SendFiles"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace org { + namespace openobex { + typedef ::OrgOpenobexClientInterface Client; + } +} +#endif diff --git a/src/bluetooth/bluez/obex_manager.cpp b/src/bluetooth/bluez/obex_manager.cpp new file mode 100644 index 00000000..7192aba8 --- /dev/null +++ b/src/bluetooth/bluez/obex_manager.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -p obex_manager_p.h:obex_manager.cpp org.openobex.all.xml org.openobex.Manager + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "obex_manager_p.h" + +/* + * Implementation of interface class OrgOpenobexManagerInterface + */ + +OrgOpenobexManagerInterface::OrgOpenobexManagerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +OrgOpenobexManagerInterface::~OrgOpenobexManagerInterface() +{ +} + diff --git a/src/bluetooth/bluez/obex_manager_p.h b/src/bluetooth/bluez/obex_manager_p.h new file mode 100644 index 00000000..673a0e7e --- /dev/null +++ b/src/bluetooth/bluez/obex_manager_p.h @@ -0,0 +1,65 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -p obex_manager_p.h:obex_manager.cpp org.openobex.all.xml org.openobex.Manager + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef OBEX_MANAGER_P_H_1291186314 +#define OBEX_MANAGER_P_H_1291186314 + +#include <QtCore/QObject> +#include <QtCore/QByteArray> +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QVariant> +#include <QtDBus/QtDBus> + +/* + * Proxy class for interface org.openobex.Manager + */ +class OrgOpenobexManagerInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "org.openobex.Manager"; } + +public: + OrgOpenobexManagerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~OrgOpenobexManagerInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> RegisterAgent(const QDBusObjectPath &in0) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0); + return asyncCallWithArgumentList(QLatin1String("RegisterAgent"), argumentList); + } + + inline QDBusPendingReply<> UnregisterAgent(const QDBusObjectPath &in0) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0); + return asyncCallWithArgumentList(QLatin1String("UnregisterAgent"), argumentList); + } + +Q_SIGNALS: // SIGNALS + void SessionCreated(const QDBusObjectPath &in0); + void SessionRemoved(const QDBusObjectPath &in0); + void TransferCompleted(const QDBusObjectPath &in0, bool in1); + void TransferStarted(const QDBusObjectPath &in0); +}; + +namespace org { + namespace openobex { + typedef ::OrgOpenobexManagerInterface Manager; + } +} +#endif diff --git a/src/bluetooth/bluez/obex_transfer.cpp b/src/bluetooth/bluez/obex_transfer.cpp new file mode 100644 index 00000000..9fad44e1 --- /dev/null +++ b/src/bluetooth/bluez/obex_transfer.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -p obex_transfer_p.h:obex_transfer.cpp org.openobex.transfer.xml org.openobex.Transfer + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "obex_transfer_p.h" + +/* + * Implementation of interface class OrgOpenobexTransferInterface + */ + +OrgOpenobexTransferInterface::OrgOpenobexTransferInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +OrgOpenobexTransferInterface::~OrgOpenobexTransferInterface() +{ +} + diff --git a/src/bluetooth/bluez/obex_transfer_p.h b/src/bluetooth/bluez/obex_transfer_p.h new file mode 100644 index 00000000..8b4fe3fd --- /dev/null +++ b/src/bluetooth/bluez/obex_transfer_p.h @@ -0,0 +1,59 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -p obex_transfer_p.h:obex_transfer.cpp org.openobex.transfer.xml org.openobex.Transfer + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef OBEX_TRANSFER_P_H_1291853849 +#define OBEX_TRANSFER_P_H_1291853849 + +#include <QtCore/QObject> +#include <QtCore/QByteArray> +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QVariant> +#include <QtDBus/QtDBus> + +/* + * Proxy class for interface org.openobex.Transfer + */ +class OrgOpenobexTransferInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "org.openobex.Transfer"; } + +public: + OrgOpenobexTransferInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~OrgOpenobexTransferInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<> Cancel() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("Cancel"), argumentList); + } + + inline QDBusPendingReply<QVariantMap> GetProperties() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace org { + namespace openobex { + typedef ::OrgOpenobexTransferInterface Transfer; + } +} +#endif diff --git a/src/bluetooth/bluez/org.bluez.Agent.xml b/src/bluetooth/bluez/org.bluez.Agent.xml new file mode 100644 index 00000000..9a77eb1b --- /dev/null +++ b/src/bluetooth/bluez/org.bluez.Agent.xml @@ -0,0 +1,32 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node name="/"> + <interface name="org.bluez.Agent"> + <method name="Release" /> + <method name="RequestPinCode"> + <arg type="o" direction="in"/> + <arg type="s" direction="out"/> + </method> + <method name="RequestPasskey"> + <arg type="o" direction="in"/> + <arg type="u" direction="out"/> + </method> + <method name="DisplayPasskey"> + <arg type="o" direction="in"/> + <arg type="u" direction="in"/> + <arg type="y" direction="in"/> + </method> + <method name="RequestConfirmation"> + <arg type="o" direction="in"/> + <arg type="u" direction="in"/> + </method> + <method name="Authorize"> + <arg type="o" direction="in"/> + <arg type="s" direction="in"/> + </method> + <method name="ConfirmModeChange"> + <arg type="s" direction="in"/> + </method> + <method name="Cancel" /> + </interface> + <node name="org"/> +</node> diff --git a/src/bluetooth/bluez/org.bluez.Device.xml b/src/bluetooth/bluez/org.bluez.Device.xml new file mode 100644 index 00000000..42351c97 --- /dev/null +++ b/src/bluetooth/bluez/org.bluez.Device.xml @@ -0,0 +1,41 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node name="/org/bluez/3003/hci0/dev_XX_XX_XX_XX_XX_XX"> + <interface name="org.bluez.Device"> + <method name="GetProperties"> + <arg type="a{sv}" direction="out"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/> + </method> + <method name="SetProperty"> + <arg type="s" direction="in"/> + <arg type="v" direction="in"/> + </method> + <method name="DiscoverServices"> + <arg type="s" direction="in"/> + <arg type="a{us}" direction="out"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="ServiceMap"/> + </method> + <method name="CancelDiscovery"/> + <method name="Disconnect"/> + <method name="ListNodes"> + <arg type="ao" direction="out"/> + </method> + <method name="CreateNode"> + <arg type="s" direction="in"/> + <arg type="o" direction="out"/> + </method> + <method name="RemoveNode"> + <arg type="o" direction="in"/> + </method> + <signal name="PropertyChanged"> + <arg type="s"/> + <arg type="v"/> + </signal> + <signal name="DisconnectRequested"/> + <signal name="NodeCreated"> + <arg type="o"/> + </signal> + <signal name="NodeRemoved"> + <arg type="o"/> + </signal> + </interface> +</node> diff --git a/src/bluetooth/bluez/org.bluez.Manager.xml b/src/bluetooth/bluez/org.bluez.Manager.xml new file mode 100644 index 00000000..60b9baba --- /dev/null +++ b/src/bluetooth/bluez/org.bluez.Manager.xml @@ -0,0 +1,25 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node name="/"> + <interface name="org.bluez.Manager"> + <method name="DefaultAdapter"> + <arg type="o" direction="out"/> + </method> + <method name="FindAdapter"> + <arg type="s" direction="in"/> + <arg type="o" direction="out"/> + </method> + <method name="ListAdapters"> + <arg type="ao" direction="out"/> + </method> + <signal name="AdapterAdded"> + <arg type="o"/> + </signal> + <signal name="AdapterRemoved"> + <arg type="o"/> + </signal> + <signal name="DefaultAdapterChanged"> + <arg type="o"/> + </signal> + </interface> + <node name="org"/> +</node> diff --git a/src/bluetooth/bluez/org.bluez.Service.xml b/src/bluetooth/bluez/org.bluez.Service.xml new file mode 100644 index 00000000..e18516a3 --- /dev/null +++ b/src/bluetooth/bluez/org.bluez.Service.xml @@ -0,0 +1,21 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node name="/org/bluez/3003/any"> + <interface name="org.bluez.Service"> + <method name="AddRecord"> + <arg type="s" direction="in"/> + <arg type="u" direction="out"/> + </method> + <method name="UpdateRecord"> + <arg type="u" direction="in"/> + <arg type="s" direction="in"/> + </method> + <method name="RemoveRecord"> + <arg type="u" direction="in"/> + </method> + <method name="RequestAuthorization"> + <arg type="s" direction="in"/> + <arg type="u" direction="in"/> + </method> + <method name="CancelAuthorization"/> + </interface> +</node> diff --git a/src/bluetooth/bluez/org.bluez.all.xml b/src/bluetooth/bluez/org.bluez.all.xml new file mode 100644 index 00000000..b48a01f3 --- /dev/null +++ b/src/bluetooth/bluez/org.bluez.all.xml @@ -0,0 +1,145 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node name="/org/bluez/3003/hci0"> + <interface name="org.bluez.Adapter"> + <method name="GetProperties"> + <arg type="a{sv}" direction="out"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/> + </method> + <method name="SetProperty"> + <arg type="s" direction="in"/> + <arg type="v" direction="in"/> + </method> + <method name="RequestMode"> + <arg type="s" direction="in"/> + </method> + <method name="ReleaseMode"/> + <method name="RequestSession"/> + <method name="ReleaseSession"/> + <method name="StartDiscovery"/> + <method name="StopDiscovery"/> + <method name="ListDevices"> + <arg type="ao" direction="out"/> + </method> + <method name="CreateDevice"> + <arg type="s" direction="in"/> + <arg type="o" direction="out"/> + </method> + <method name="CreatePairedDevice"> + <arg type="s" direction="in"/> + <arg type="o" direction="in"/> + <arg type="s" direction="in"/> + <arg type="o" direction="out"/> + </method> + <method name="CancelDeviceCreation"> + <arg type="s" direction="in"/> + </method> + <method name="RemoveDevice"> + <arg type="o" direction="in"/> + </method> + <method name="FindDevice"> + <arg type="s" direction="in"/> + <arg type="o" direction="out"/> + </method> + <method name="RegisterAgent"> + <arg type="o" direction="in"/> + <arg type="s" direction="in"/> + </method> + <method name="UnregisterAgent"> + <arg type="o" direction="in"/> + </method> + <signal name="DeviceCreated"> + <arg type="o"/> + </signal> + <signal name="DeviceRemoved"> + <arg type="o"/> + </signal> + <signal name="DeviceFound"> + <arg type="s"/> + <arg type="a{sv}"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="QVariantMap"/> + </signal> + <signal name="PropertyChanged"> + <arg type="s"/> + <arg type="v"/> + </signal> + <signal name="DeviceDisappeared"> + <arg type="s"/> + </signal> + </interface> + <interface name="org.bluez.Service"> + <method name="AddRecord"> + <arg type="s" direction="in"/> + <arg type="u" direction="out"/> + </method> + <method name="UpdateRecord"> + <arg type="u" direction="in"/> + <arg type="s" direction="in"/> + </method> + <method name="RemoveRecord"> + <arg type="u" direction="in"/> + </method> + <method name="RequestAuthorization"> + <arg type="s" direction="in"/> + <arg type="u" direction="in"/> + </method> + <method name="CancelAuthorization"/> + </interface> + <interface name="org.bluez.SerialProxyManager"> + <method name="CreateProxy"> + <arg type="s" direction="in"/> + <arg type="s" direction="in"/> + <arg type="s" direction="out"/> + </method> + <method name="ListProxies"> + <arg type="as" direction="out"/> + </method> + <method name="RemoveProxy"> + <arg type="s" direction="in"/> + </method> + <signal name="ProxyCreated"> + <arg type="s"/> + </signal> + <signal name="ProxyRemoved"> + <arg type="s"/> + </signal> + </interface> + <interface name="org.bluez.NetworkPeer"> + <method name="SetProperty"> + <arg type="s" direction="in"/> + <arg type="v" direction="in"/> + </method> + <method name="GetProperties"> + <arg type="a{sv}" direction="out"/> + </method> + <signal name="PropertyChanged"> + <arg type="s"/> + <arg type="v"/> + </signal> + </interface> + <interface name="org.bluez.NetworkHub"> + <method name="SetProperty"> + <arg type="s" direction="in"/> + <arg type="v" direction="in"/> + </method> + <method name="GetProperties"> + <arg type="a{sv}" direction="out"/> + </method> + <signal name="PropertyChanged"> + <arg type="s"/> + <arg type="v"/> + </signal> + </interface> + <interface name="org.bluez.NetworkRouter"> + <method name="SetProperty"> + <arg type="s" direction="in"/> + <arg type="v" direction="in"/> + </method> + <method name="GetProperties"> + <arg type="a{sv}" direction="out"/> + </method> + <signal name="PropertyChanged"> + <arg type="s"/> + <arg type="v"/> + </signal> + </interface> +</node> diff --git a/src/bluetooth/bluez/org.openobex.agent.xml b/src/bluetooth/bluez/org.openobex.agent.xml new file mode 100644 index 00000000..d21f3149 --- /dev/null +++ b/src/bluetooth/bluez/org.openobex.agent.xml @@ -0,0 +1,24 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node> + <interface name="org.openobex.Agent"> + <method name="Release"> + </method> + <method name="Request"> + <arg type="o" direction="in"/> + <arg type="s" direction="out"/> + </method> + <method name="Progress"> + <arg type="o" direction="in"/> + <arg type="t" direction="in"/> + </method> + <method name="Complete"> + <arg type="o" direction="in"/> + </method> + <method name="Error"> + <arg type="o" direction="in"/> + <arg type="s" direction="in"/> + </method> + </interface> +</node> + diff --git a/src/bluetooth/bluez/org.openobex.all.xml b/src/bluetooth/bluez/org.openobex.all.xml new file mode 100644 index 00000000..4e5b65b2 --- /dev/null +++ b/src/bluetooth/bluez/org.openobex.all.xml @@ -0,0 +1,31 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node name="/"> + <interface name="org.freedesktop.DBus.Introspectable"> + <method name="Introspect"> + <arg type="s" direction="out"/> + </method> + </interface> + <interface name="org.openobex.Manager"> + <method name="RegisterAgent"> + <arg type="o" direction="in"/> + </method> + <method name="UnregisterAgent"> + <arg type="o" direction="in"/> + </method> + <signal name="TransferStarted"> + <arg type="o"/> + </signal> + <signal name="TransferCompleted"> + <arg type="o"/> + <arg type="b"/> + </signal> + <signal name="SessionCreated"> + <arg type="o"/> + </signal> + <signal name="SessionRemoved"> + <arg type="o"/> + </signal> + </interface> +</node> + diff --git a/src/bluetooth/bluez/org.openobex.client.xml b/src/bluetooth/bluez/org.openobex.client.xml new file mode 100644 index 00000000..fad2f6ef --- /dev/null +++ b/src/bluetooth/bluez/org.openobex.client.xml @@ -0,0 +1,40 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node name="/"> + <interface name="org.freedesktop.DBus.Introspectable"> + <method name="Introspect"> + <arg type="s" direction="out"/> + </method> + </interface> + <interface name="org.openobex.Client"> + <method name="SendFiles"> + <arg type="a{sv}" direction="in"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="QVariantMap"/> + <arg type="as" direction="in"/> + <arg type="o" direction="in"/> + </method> + <method name="PullBusinessCard"> + <arg type="a{sv}" direction="in"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="QVariantMap"/> + <arg type="s" direction="in"/> + </method> + <method name="ExchangeBusinessCards"> + <arg type="a{sv}" direction="in"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="QVariantMap"/> + <arg type="s" direction="in"/> + <arg type="s" direction="in"/> + </method> + <method name="CreateSession"> + <arg type="a{sv}" direction="in"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="QVariantMap"/> + <arg type="o" direction="out"/> + </method> + <method name="GetCapabilities"> + <arg type="a{sv}" direction="in"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="QVariantMap"/> + <arg type="s" direction="out"/> + </method> + </interface> + <node name="org"/> +</node> + diff --git a/src/bluetooth/bluez/org.openobex.transfer.xml b/src/bluetooth/bluez/org.openobex.transfer.xml new file mode 100644 index 00000000..21033665 --- /dev/null +++ b/src/bluetooth/bluez/org.openobex.transfer.xml @@ -0,0 +1,19 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node name="/"> + <interface name="org.freedesktop.DBus.Introspectable"> + <method name="Introspect"> + <arg type="s" direction="out"/> + </method> + </interface> + <interface name="org.openobex.Transfer"> + <method name="GetProperties"> + <arg type="a{sv}" direction="out"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QVariantMap"/> + </method> + <method name="Cancel"> + </method> + </interface> + <node name="org"/> +</node> + diff --git a/src/bluetooth/bluez/service.cpp b/src/bluetooth/bluez/service.cpp new file mode 100644 index 00000000..811eb2fd --- /dev/null +++ b/src/bluetooth/bluez/service.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -p service_p.h:service.cpp org.bluez.all.xml org.bluez.Service + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "service_p.h" + +/* + * Implementation of interface class OrgBluezServiceInterface + */ + +OrgBluezServiceInterface::OrgBluezServiceInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +OrgBluezServiceInterface::~OrgBluezServiceInterface() +{ +} + diff --git a/src/bluetooth/bluez/service_p.h b/src/bluetooth/bluez/service_p.h new file mode 100644 index 00000000..dd0f69d6 --- /dev/null +++ b/src/bluetooth/bluez/service_p.h @@ -0,0 +1,81 @@ +/* + * This file was generated by qdbusxml2cpp version 0.7 + * Command line was: qdbusxml2cpp -p service_p.h:service.cpp org.bluez.all.xml org.bluez.Service + * + * qdbusxml2cpp is Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef SERVICE_P_H_1277421939 +#define SERVICE_P_H_1277421939 + +#include <QtCore/QObject> +#include <QtCore/QByteArray> +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QString> +#include <QtCore/QStringList> +#include <QtCore/QVariant> +#include <QtDBus/QtDBus> + +/* + * Proxy class for interface org.bluez.Service + */ +class OrgBluezServiceInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "org.bluez.Service"; } + +public: + OrgBluezServiceInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + + ~OrgBluezServiceInterface(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply<uint> AddRecord(const QString &in0) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0); + return asyncCallWithArgumentList(QLatin1String("AddRecord"), argumentList); + } + + inline QDBusPendingReply<> CancelAuthorization() + { + QList<QVariant> argumentList; + return asyncCallWithArgumentList(QLatin1String("CancelAuthorization"), argumentList); + } + + inline QDBusPendingReply<> RemoveRecord(uint in0) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0); + return asyncCallWithArgumentList(QLatin1String("RemoveRecord"), argumentList); + } + + inline QDBusPendingReply<> RequestAuthorization(const QString &in0, uint in1) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0) << qVariantFromValue(in1); + return asyncCallWithArgumentList(QLatin1String("RequestAuthorization"), argumentList); + } + + inline QDBusPendingReply<> UpdateRecord(uint in0, const QString &in1) + { + QList<QVariant> argumentList; + argumentList << qVariantFromValue(in0) << qVariantFromValue(in1); + return asyncCallWithArgumentList(QLatin1String("UpdateRecord"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +namespace org { + namespace bluez { + typedef ::OrgBluezServiceInterface Service; + } +} +#endif diff --git a/src/bluetooth/bluez/servicemap.cpp b/src/bluetooth/bluez/servicemap.cpp new file mode 100644 index 00000000..5e9a2995 --- /dev/null +++ b/src/bluetooth/bluez/servicemap.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "servicemap_p.h" + +const QDBusArgument &operator>>(const QDBusArgument &argument, ServiceMap &serviceMap) +{ + argument.beginMap(); + + while (!argument.atEnd()) { + quint32 uuid; + QString service; + + argument.beginMapEntry(); + argument >> uuid; + argument >> service; + argument.endMapEntry(); + + serviceMap.insert(uuid, service); + } + + argument.endMap(); + + return argument; +} diff --git a/src/bluetooth/bluez/servicemap_p.h b/src/bluetooth/bluez/servicemap_p.h new file mode 100644 index 00000000..4504d4d6 --- /dev/null +++ b/src/bluetooth/bluez/servicemap_p.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SERVICEMAP_P_H +#define SERVICEMAP_P_H + +#include <QtCore/QMap> +#include <QtCore/QString> +#include <QtDBus/QDBusArgument> + +typedef QMap<quint32, QString> ServiceMap; + +const QDBusArgument &operator>>(const QDBusArgument &argument, ServiceMap &serviceMap); + +Q_DECLARE_METATYPE(ServiceMap) + +#endif // SERVICEMAP_P_H diff --git a/src/bluetooth/qbluetooth.cpp b/src/bluetooth/qbluetooth.cpp new file mode 100644 index 00000000..89b6b89b --- /dev/null +++ b/src/bluetooth/qbluetooth.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetooth.h" + +/*! + \namespace QBluetooth + \brief The QBluetooth namespace contains functions and definitions related to Bluetooth. + \since 5.0 + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity +*/ + +/*! + \enum QBluetooth::Security + + This enum describe the security requirements of a Bluetooth service. + + \value NoSecurity The service does not require any security. + + \value Authorization The service requires authorization. Device does not + have to paired, the connection will be granted by prompting the user unless + the device is Authorized-Paired where the connection will be made + automatically. + + \value Authentication The service requires authentication. Device must + paired, the user maybe prompted on connection unless the device is + Authorized-Paired. + + \value Encryption The service requires that the communications link be + encrypted. This requires the device be paired. + + \value Secure The service requires that the communications link be secure. + Legacy pairing is not permitted, Simple Pairing from Bluetooth 2.1 or + greater is required. +*/ diff --git a/src/bluetooth/qbluetooth.h b/src/bluetooth/qbluetooth.h new file mode 100644 index 00000000..f79c71a9 --- /dev/null +++ b/src/bluetooth/qbluetooth.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QBLUETOOTH_H +#define QBLUETOOTH_H + +#include "../qtconnectivityglobal.h" + +QT_BEGIN_HEADER + +namespace QBluetooth { +enum Security { + NoSecurity = 0x00, + Authorization = 0x01, + Authentication = 0x02, + Encryption = 0x04, + Secure = 0x08 +}; + +Q_DECLARE_FLAGS(SecurityFlags, Security) + +Q_DECLARE_OPERATORS_FOR_FLAGS(SecurityFlags) + +} + +QT_END_HEADER + +#endif // QBLUETOOTH_H diff --git a/src/bluetooth/qbluetoothaddress.cpp b/src/bluetooth/qbluetoothaddress.cpp new file mode 100644 index 00000000..d5467b9f --- /dev/null +++ b/src/bluetooth/qbluetoothaddress.cpp @@ -0,0 +1,217 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothaddress.h" +#include "qbluetoothaddress_p.h" + +/*! + \class QBluetoothAddress + \brief The QBluetoothAddress class provides a Bluetooth address. + \since 5.0 + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity + + This class holds a Bluetooth address in a platform- and protocol- independent manner. +*/ + +/*! + \fn inline bool QBluetoothAddress::operator!=(const QBluetoothAddress &other) const + + + Compares this Bluetooth address with \a other. + + Returns true if the Bluetooth addresses are not equal, otherwise returns false. +*/ + +namespace +{ +class BluetoothAddressRegisterMetaTypes +{ +public: + BluetoothAddressRegisterMetaTypes() + { + qRegisterMetaType<QBluetoothAddress>("QBluetoothAddress"); + } +} _registerBluetoothAddressMetaTypes; +} + +/*! + Constructs an null Bluetooth address. +*/ +QBluetoothAddress::QBluetoothAddress() + : d_ptr(new QBluetoothAddressPrivate) +{ +} + +/*! + Constructs a new Bluetooth address and assigns \a address to it. +*/ +QBluetoothAddress::QBluetoothAddress(quint64 address) + : d_ptr(new QBluetoothAddressPrivate) +{ + Q_D(QBluetoothAddress); + d->m_address = address; +} + +/*! + Constructs a new Bluetooth address and assigns \a address to it. + + The format of \a address can be either XX:XX:XX:XX:XX:XX or XXXXXXXXXXXX, + where X is a hexadecimal digit. Case is not important. +*/ +QBluetoothAddress::QBluetoothAddress(const QString &address) + : d_ptr(new QBluetoothAddressPrivate) +{ + Q_D(QBluetoothAddress); + + QString a = address; + + if (a.length() == 17) + a.remove(QLatin1Char(':')); + + if (a.length() == 12) { + bool ok; + d->m_address = a.toULongLong(&ok, 16); + if (!ok) + clear(); + } else { + d->m_address = 0; + } +} + +/*! + Constructs a new Bluetooth address which is a copy of \a other. +*/ +QBluetoothAddress::QBluetoothAddress(const QBluetoothAddress &other) + : d_ptr(new QBluetoothAddressPrivate) +{ + *this = other; +} + +/*! + Destroys the QBluetoothAddress. +*/ +QBluetoothAddress::~QBluetoothAddress() +{ + delete d_ptr; +} + +/*! + Assigns \a other to this Bluetooth address. +*/ +QBluetoothAddress &QBluetoothAddress::operator=(const QBluetoothAddress &other) +{ + Q_D(QBluetoothAddress); + + d->m_address = other.d_func()->m_address; + + return *this; +} + +/*! + Sets the Bluetooth address to 00:00:00:00:00:00. +*/ +void QBluetoothAddress::clear() +{ + Q_D(QBluetoothAddress); + d->m_address = 0; +} + +/*! + Returns true if the Bluetooth address is valid, otherwise returns false. +*/ +bool QBluetoothAddress::isNull() const +{ + Q_D(const QBluetoothAddress); + return d->m_address == 0; +} + +/*! + Returns true if the Bluetooth address is less than \a other; otherwise + returns false. +*/ +bool QBluetoothAddress::operator<(const QBluetoothAddress &other) const +{ + Q_D(const QBluetoothAddress); + return d->m_address < other.d_func()->m_address; +} + +/*! + Compares this Bluetooth address to \a other. + + Returns true if the Bluetooth address are equal, otherwise returns false. +*/ +bool QBluetoothAddress::operator==(const QBluetoothAddress &other) const +{ + Q_D(const QBluetoothAddress); + return d->m_address == other.d_func()->m_address; +} + +/*! + Returns this Bluetooth address as a quint64. +*/ +quint64 QBluetoothAddress::toUInt64() const +{ + Q_D(const QBluetoothAddress); + return d->m_address; +} + +/*! + Returns the Bluetooth address as a string of the form XX:XX:XX:XX:XX:XX. +*/ +QString QBluetoothAddress::toString() const +{ + QString s(QLatin1String("%1:%2:%3:%4:%5:%6")); + Q_D(const QBluetoothAddress); + + for (int i = 5; i >= 0; --i) { + const quint8 a = (d->m_address >> (i*8)) & 0xff; + s = s.arg(a, 2, 16, QLatin1Char('0')); + } + + return s.toUpper(); +} + +QBluetoothAddressPrivate::QBluetoothAddressPrivate() +{ + m_address = 0; +} diff --git a/src/bluetooth/qbluetoothaddress.h b/src/bluetooth/qbluetoothaddress.h new file mode 100644 index 00000000..1ba79bad --- /dev/null +++ b/src/bluetooth/qbluetoothaddress.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHADDRESS_H +#define QBLUETOOTHADDRESS_H + +#include "../qtconnectivityglobal.h" + +#include <QtCore/QByteArray> +#include <QtCore/QString> +#include <QtCore/QMetaType> + +QT_BEGIN_HEADER + +class QBluetoothAddressPrivate; + +class Q_CONNECTIVITY_EXPORT QBluetoothAddress +{ +public: + QBluetoothAddress(); + explicit QBluetoothAddress(quint64 address); + explicit QBluetoothAddress(const QString &address); + QBluetoothAddress(const QBluetoothAddress &other); + ~QBluetoothAddress(); + + QBluetoothAddress &operator=(const QBluetoothAddress &other); + + bool isNull() const; + + void clear(); + + bool operator<(const QBluetoothAddress &other) const; + bool operator==(const QBluetoothAddress &other) const; + inline bool operator!=(const QBluetoothAddress &other) const { return !operator==(other); } + + quint64 toUInt64() const; + QString toString() const; + +private: + Q_DECLARE_PRIVATE(QBluetoothAddress) + QBluetoothAddressPrivate *d_ptr; +}; + +Q_DECLARE_METATYPE(QBluetoothAddress) + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/qbluetoothaddress_p.h b/src/bluetooth/qbluetoothaddress_p.h new file mode 100644 index 00000000..f7d1073e --- /dev/null +++ b/src/bluetooth/qbluetoothaddress_p.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHADDRESS_P_H +#define QBLUETOOTHADDRESS_P_H + +#include "qbluetoothaddress.h" + +QT_BEGIN_HEADER + +class QBluetoothAddressPrivate +{ +public: + QBluetoothAddressPrivate(); + + + quint64 m_address; + +}; + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent.cpp new file mode 100644 index 00000000..342c8d3d --- /dev/null +++ b/src/bluetooth/qbluetoothdevicediscoveryagent.cpp @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothdevicediscoveryagent.h" +#include "qbluetoothdevicediscoveryagent_p.h" + +/*! + \class QBluetoothDeviceDiscoveryAgent + \brief The QBluetoothDeviceDiscoveryAgent class provides an API for discovering nearby + Bluetooth devices. + \since 5.0 + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity + + To discovery nearby Bluetooth devices create an instance of QBluetoothDeviceDiscoveryAgent, + connect to either the deviceDiscovered() or finished() signals and call start(). + + \snippet snippets/connectivity/devicediscovery.cpp Device discovery + + To retrieve results asynchronously connect to the deviceDiscovered() signal. To get a list of + all discovered devices call discoveredDevices() after the finished() signal is emitted. +*/ + +/*! + \enum QBluetoothDeviceDiscoveryAgent::Error + + Indicates all possible error conditions found during Bluetooth device discovery. + + \value NoError No error has occurred. + \value PoweredOff Bluetooth adaptor is powered off, power it on before doing discovery. + \value IOFailure Writing or reading from device resulted in an error. + \value UnknownError An unknown error has occurred. +*/ + +/*! + \enum QBluetoothDeviceDiscoveryAgent::InquiryType + + This enum describes the inquiry type used when discovering Bluetooth devices. + + \value GeneralUnlimitedInquiry A general unlimited inquiry. Discovers all visible Bluetooth + devices in the local vicinity. + \value LimitedInquiry A limited inquiry. Only discovers devices that are in limited + inquiry mode. Not all platforms support limited inquiry. If + limited inquiry is requested on a platform that does not + support it general unlimited inquiry we be used instead. Setting + LimitedInquiry is useful for 2 games that wish to find each other + quickly. The phone scans for devices in LimitedInquiry and + Service Discovery is only done on one or two devices speeding up the + service scan. After the game has connected the device returns to + GeneralUnilimitedInquiry +*/ + +/*! + \fn void QBluetoothDeviceDiscoveryAgent::deviceDiscovered(const QBluetoothDeviceInfo &info) + + This signal is emitted when the Bluetooth device described by \a info is discovered. +*/ + +/*! + \fn void QBluetoothDeviceDiscoveryAgent::finished() + + This signal is emitted when Bluetooth device discovery completes. +*/ + +/*! + \fn void QBluetoothDeviceDiscoveryAgent::error(QBluetoothDeviceDiscoveryAgent::Error error) + + This signal is emitted when an \a error occurs during Bluetooth device discovery. + + \sa error(), errorString() +*/ + +/*! + \fn void QBluetoothDeviceDiscoveryAgent::canceled() + + This signal is emitted when device discovery is aborted by a call to stop(). +*/ + +/*! + \fn bool QBluetoothDeviceDiscoveryAgent::isActive() const + + Returns true if the agent is currently discovering Bluetooth devices, other returns false. +*/ + +/*! + Constructs a new Bluetooth device discovery agent with parent \a parent. +*/ +QBluetoothDeviceDiscoveryAgent::QBluetoothDeviceDiscoveryAgent(QObject *parent) +: QObject(parent), d_ptr(new QBluetoothDeviceDiscoveryAgentPrivate) +{ + d_ptr->q_ptr = this; +} + +/*! + Destructor for ~QBluetoothDeviceDiscoveryAgent() +*/ +QBluetoothDeviceDiscoveryAgent::~QBluetoothDeviceDiscoveryAgent() +{ + delete d_ptr; +} + +/*! + \property QBluetoothDeviceDiscoveryAgent::inquiryType + \brief type of inquiry scan to use when discovering devices + + This property affects the type of inquiry scan which is performed when discovering devices. + + By default, this property is set to GeneralUnlimitedInquiry. + + Not all platforms support LimitedInquiry. + + \sa InquiryType +*/ +QBluetoothDeviceDiscoveryAgent::InquiryType QBluetoothDeviceDiscoveryAgent::inquiryType() const +{ + Q_D(const QBluetoothDeviceDiscoveryAgent); + return d->inquiryType; +} + +void QBluetoothDeviceDiscoveryAgent::setInquiryType(QBluetoothDeviceDiscoveryAgent::InquiryType type) +{ + Q_D(QBluetoothDeviceDiscoveryAgent); + d->inquiryType = type; +} + +/*! + Returns a list of all discovered Bluetooth devices. +*/ +QList<QBluetoothDeviceInfo> QBluetoothDeviceDiscoveryAgent::discoveredDevices() const +{ + Q_D(const QBluetoothDeviceDiscoveryAgent); + return d->discoveredDevices; +} + +/*! + Starts Bluetooth device discovery, if it is not already started. + + The deviceDiscovered() signal is emitted as each device is discovered. The finished() signal + is emitted once device discovery is complete. +*/ +void QBluetoothDeviceDiscoveryAgent::start() +{ + Q_D(QBluetoothDeviceDiscoveryAgent); + if (!isActive()) + d->start(); +} + +/*! + Stops Bluetooth device discovery. The cancel() signal is emitted once the + device discovery is canceled. start() maybe called before the cancel signal is + received. Once start() has been called the cancel signal from the prior + discovery will be silently discarded. +*/ +void QBluetoothDeviceDiscoveryAgent::stop() +{ + Q_D(QBluetoothDeviceDiscoveryAgent); + if (isActive()) + d->stop(); +} + +bool QBluetoothDeviceDiscoveryAgent::isActive() const +{ + Q_D(const QBluetoothDeviceDiscoveryAgent); + return d->isActive(); +} + + +/*! + Returns the last error which has occurred. +*/ +QBluetoothDeviceDiscoveryAgent::Error QBluetoothDeviceDiscoveryAgent::error() const +{ + Q_D(const QBluetoothDeviceDiscoveryAgent); + + return d->lastError; +} + +/*! + Returns a human-readable description of the last error that occurred. +*/ +QString QBluetoothDeviceDiscoveryAgent::errorString() const +{ + Q_D(const QBluetoothDeviceDiscoveryAgent); + return d->errorString; +} + +#include "moc_qbluetoothdevicediscoveryagent.cpp" diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent.h b/src/bluetooth/qbluetoothdevicediscoveryagent.h new file mode 100644 index 00000000..9502e900 --- /dev/null +++ b/src/bluetooth/qbluetoothdevicediscoveryagent.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHDEVICEDISCOVERYAGENT_H +#define QBLUETOOTHDEVICEDISCOVERYAGENT_H + +#include "../qtconnectivityglobal.h" + +#include <QObject> + +#include <qbluetoothdeviceinfo.h> + +QT_BEGIN_HEADER + +class QBluetoothDeviceDiscoveryAgentPrivate; + +class Q_CONNECTIVITY_EXPORT QBluetoothDeviceDiscoveryAgent : public QObject +{ + Q_OBJECT + Q_PROPERTY(QBluetoothDeviceDiscoveryAgent::InquiryType inquiryType READ inquiryType WRITE setInquiryType) + +public: + // FIXME: add more errors + // FIXME: add bluez error handling + enum Error { + NoError, + IOFailure, + PoweredOff, + UnknownError = 100 + }; + + enum InquiryType { + GeneralUnlimitedInquiry, + LimitedInquiry, + }; + + QBluetoothDeviceDiscoveryAgent(QObject *parent = 0); + ~QBluetoothDeviceDiscoveryAgent(); + + QBluetoothDeviceDiscoveryAgent::InquiryType inquiryType() const; + void setInquiryType(QBluetoothDeviceDiscoveryAgent::InquiryType type); + + bool isActive() const; + + Error error() const; + QString errorString() const; + + QList<QBluetoothDeviceInfo> discoveredDevices() const; + +public slots: + void start(); + void stop(); + +signals: + void deviceDiscovered(const QBluetoothDeviceInfo &info); + void finished(); + void error(QBluetoothDeviceDiscoveryAgent::Error error); + void canceled(); + +private: + Q_DECLARE_PRIVATE(QBluetoothDeviceDiscoveryAgent) + QBluetoothDeviceDiscoveryAgentPrivate *d_ptr; + +#ifdef QT_BLUEZ_BLUETOOTH + Q_PRIVATE_SLOT(d_func(), void _q_deviceFound(const QString &address, const QVariantMap &dict)); + Q_PRIVATE_SLOT(d_func(), void _q_propertyChanged(const QString &name, const QDBusVariant &value)); +#endif + +#ifdef QT_SYMBIAN_BLUETOOTH + Q_PRIVATE_SLOT(d_func(), void _q_newDeviceFound(const QBluetoothDeviceInfo &device)) + Q_PRIVATE_SLOT(d_func(), void _q_setError(QBluetoothDeviceDiscoveryAgent::Error errorCode, QString errorDescription)) +#endif // QT_SYMBIAN_BLUETOOTH +}; + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp new file mode 100644 index 00000000..3a510afa --- /dev/null +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp @@ -0,0 +1,222 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothdevicediscoveryagent.h" +#include "qbluetoothdevicediscoveryagent_p.h" +#include "qbluetoothaddress.h" +#include "qbluetoothuuid.h" + +#include "bluez/manager_p.h" +#include "bluez/adapter_p.h" +#include "bluez/device_p.h" + +//#define QTM_DEVICEDISCOVERY_DEBUG + +QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate() + : lastError(QBluetoothDeviceDiscoveryAgent::NoError), pendingCancel(false), pendingStart(false), adapter(0) +{ + manager = new OrgBluezManagerInterface(QLatin1String("org.bluez"), QLatin1String("/"), + QDBusConnection::systemBus()); + inquiryType = QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry; +} + +QBluetoothDeviceDiscoveryAgentPrivate::~QBluetoothDeviceDiscoveryAgentPrivate() +{ + delete manager; +} + +bool QBluetoothDeviceDiscoveryAgentPrivate::isActive() const +{ + if(pendingStart) + return true; + if(pendingCancel) + return false; + return adapter != 0; +} + +void QBluetoothDeviceDiscoveryAgentPrivate::start() +{ + + if(pendingCancel == true) { + pendingStart = true; + return; + } + + discoveredDevices.clear(); + + QDBusPendingReply<QDBusObjectPath> reply = manager->DefaultAdapter(); + reply.waitForFinished(); + if (reply.isError()) { + errorString = reply.error().message(); +#ifdef QTM_DEVICEDISCOVERY_DEBUG + qDebug() << Q_FUNC_INFO << "ERROR: " << errorString; +#endif + lastError = QBluetoothDeviceDiscoveryAgent::IOFailure; + Q_Q(QBluetoothDeviceDiscoveryAgent); + emit q->error(lastError); + return; + } + + adapter = new OrgBluezAdapterInterface(QLatin1String("org.bluez"), reply.value().path(), + QDBusConnection::systemBus()); + + Q_Q(QBluetoothDeviceDiscoveryAgent); + QObject::connect(adapter, SIGNAL(DeviceFound(QString,QVariantMap)), + q, SLOT(_q_deviceFound(QString,QVariantMap))); + QObject::connect(adapter, SIGNAL(PropertyChanged(QString,QDBusVariant)), + q, SLOT(_q_propertyChanged(QString,QDBusVariant))); + + QDBusPendingReply<QVariantMap> propertiesReply = adapter->GetProperties(); + propertiesReply.waitForFinished(); + if(propertiesReply.isError()) { +#ifdef QTM_DEVICEDISCOVERY_DEBUG + qDebug() << Q_FUNC_INFO << "ERROR: " << errorString; +#endif + errorString = propertiesReply.error().message(); + lastError = QBluetoothDeviceDiscoveryAgent::IOFailure; + Q_Q(QBluetoothDeviceDiscoveryAgent); + emit q->error(lastError); + return; + } + + QDBusPendingReply<> discoveryReply = adapter->StartDiscovery(); + if (discoveryReply.isError()) { + delete adapter; + adapter = 0; + errorString = discoveryReply.error().message(); + lastError = QBluetoothDeviceDiscoveryAgent::IOFailure; + Q_Q(QBluetoothDeviceDiscoveryAgent); + emit q->error(lastError); +#ifdef QTM_DEVICEDISCOVERY_DEBUG + qDebug() << Q_FUNC_INFO << "ERROR: " << errorString; +#endif + return; + } +} + +void QBluetoothDeviceDiscoveryAgentPrivate::stop() +{ + if (adapter) { +#ifdef QTM_DEVICEDISCOVERY_DEBUG + qDebug() << Q_FUNC_INFO; +#endif + pendingCancel = true; + pendingStart = false; + QDBusPendingReply<> reply = adapter->StopDiscovery(); + reply.waitForFinished(); + } +} + +void QBluetoothDeviceDiscoveryAgentPrivate::_q_deviceFound(const QString &address, + const QVariantMap &dict) +{ + const QBluetoothAddress btAddress(address); + const QString btName = dict.value(QLatin1String("Name")).toString(); + quint32 btClass = dict.value(QLatin1String("Class")).toUInt(); + +#ifdef QTM_DEVICEDISCOVERY_DEBUG + qDebug() << "Discovered: " << address << btName + << "Num UUIDs" << dict.value(QLatin1String("UUIDs")).toStringList().count() + << "total device" << discoveredDevices.count() << "cached" + << dict.value(QLatin1String("Cached")).toBool() + << "RSSI" << dict.value(QLatin1String("RSSI")).toInt(); +#endif + + QBluetoothDeviceInfo device(btAddress, btName, btClass); + if(dict.value(QLatin1String("RSSI")).isValid()) + device.setRssi(dict.value(QLatin1String("RSSI")).toInt()); + QList<QBluetoothUuid> uuids; + foreach (const QString &u, dict.value(QLatin1String("UUIDs")).toStringList()) { + uuids.append(QBluetoothUuid(u)); + } + device.setServiceUuids(uuids, QBluetoothDeviceInfo::DataIncomplete); + device.setCached(dict.value(QLatin1String("Cached")).toBool()); + for(int i = 0; i < discoveredDevices.size(); i++){ + if(discoveredDevices[i].address() == device.address()) { + if(discoveredDevices[i] == device) { +#ifdef QTM_DEVICEDISCOVERY_DEBUG + qDebug() << "Duplicate: " << address; +#endif + return; + } + discoveredDevices.replace(i, device); + Q_Q(QBluetoothDeviceDiscoveryAgent); +#ifdef QTM_DEVICEDISCOVERY_DEBUG + qDebug() << "Updated: " << address; +#endif + + emit q->deviceDiscovered(device); + return; // this works if the list doesn't contain duplicates. Don't let it. + } + } +#ifdef QTM_DEVICEDISCOVERY_DEBUG + qDebug() << "Emit: " << address; +#endif + discoveredDevices.append(device); + Q_Q(QBluetoothDeviceDiscoveryAgent); + emit q->deviceDiscovered(device); +} + +void QBluetoothDeviceDiscoveryAgentPrivate::_q_propertyChanged(const QString &name, + const QDBusVariant &value) +{ +#ifdef QTM_DEVICEDISCOVERY_DEBUG + qDebug() << Q_FUNC_INFO << name << value.variant(); +#endif + + if (name == QLatin1String("Discovering") && !value.variant().toBool()) { + Q_Q(QBluetoothDeviceDiscoveryAgent); + adapter->deleteLater(); + adapter = 0; + if(pendingCancel && !pendingStart){ + emit q->canceled(); + pendingCancel = false; + } + else if(pendingStart){ + pendingStart = false; + pendingCancel = false; + start(); + } + else { + emit q->finished(); + } + } +} diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_p.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_p.cpp new file mode 100644 index 00000000..83b4a623 --- /dev/null +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_p.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothdevicediscoveryagent.h" +#include "qbluetoothdevicediscoveryagent_p.h" +#include "qbluetoothaddress.h" +#include "qbluetoothuuid.h" + +#define QTM_DEVICEDISCOVERY_DEBUG + +QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate() + +{ +} + +QBluetoothDeviceDiscoveryAgentPrivate::~QBluetoothDeviceDiscoveryAgentPrivate() +{ +} + +bool QBluetoothDeviceDiscoveryAgentPrivate::isActive() const +{ + return false; +} + +void QBluetoothDeviceDiscoveryAgentPrivate::start() +{ +} + +void QBluetoothDeviceDiscoveryAgentPrivate::stop() +{ +} +#ifdef QT_BLUEZ_BLUETOOTH +void QBluetoothDeviceDiscoveryAgentPrivate::_q_deviceFound(const QString &address, + const QVariantMap &dict) +{ + Q_UNUSED(address); + Q_UNUSED(dict); +} + +void QBluetoothDeviceDiscoveryAgentPrivate::_q_propertyChanged(const QString &name, + const QDBusVariant &value) +{ + Q_UNUSED(name); + Q_UNUSED(value); +} +#endif + +#ifdef QT_SYMBIAN_BLUETOOTH +void _q_newDeviceFound(const QBluetoothDeviceInfo &device) +{ + +} +#endif + diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_p.h b/src/bluetooth/qbluetoothdevicediscoveryagent_p.h new file mode 100644 index 00000000..247ee1c8 --- /dev/null +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_p.h @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHDEVICEDISCOVERYAGENT_P_H +#define QBLUETOOTHDEVICEDISCOVERYAGENT_P_H + +#include "qbluetoothdevicediscoveryagent.h" + +#include <QVariantMap> + +#ifdef QT_BLUEZ_BLUETOOTH +class OrgBluezManagerInterface; +class OrgBluezAdapterInterface; +class QDBusVariant; +#endif + +#ifdef QT_SYMBIAN_BLUETOOTH +#include "symbian/bluetoothlinkmanagerdevicediscoverer.h" +#include <es_sock.h> +#include <bt_sock.h> +#endif + +QT_BEGIN_HEADER + +class QBluetoothDeviceDiscoveryAgentPrivate +{ + Q_DECLARE_PUBLIC(QBluetoothDeviceDiscoveryAgent) +public: + QBluetoothDeviceDiscoveryAgentPrivate(); + ~QBluetoothDeviceDiscoveryAgentPrivate(); + + void start(); + void stop(); + bool isActive() const; + +#ifdef QT_SYMBIAN_BLUETOOTH +// private slots + void _q_newDeviceFound(const QBluetoothDeviceInfo &device); + void _q_setError(QBluetoothDeviceDiscoveryAgent::Error errorCode, + QString errorDescription); +#endif + +#ifdef QT_BLUEZ_BLUETOOTH + void _q_deviceFound(const QString &address, const QVariantMap &dict); + void _q_propertyChanged(const QString &name, const QDBusVariant &value); +#endif + +private: +#ifdef QT_SYMBIAN_BLUETOOTH + void allocate(); + uint inquiryTypeToIAC() const; +#endif + + QList<QBluetoothDeviceInfo> discoveredDevices; + QBluetoothDeviceDiscoveryAgent::InquiryType inquiryType; + + QBluetoothDeviceDiscoveryAgent::Error lastError; + QString errorString; + + bool pendingCancel; + bool pendingStart; + +#ifdef QT_BLUEZ_BLUETOOTH + OrgBluezManagerInterface *manager; + OrgBluezAdapterInterface *adapter; +#endif + +#ifdef QT_SYMBIAN_BLUETOOTH + // shared socket servet among RHostResolvers + RSocketServ m_socketServer; + // active object for device discovery + BluetoothLinkManagerDeviceDiscoverer *m_deviceDiscovery; + +#endif + + QBluetoothDeviceDiscoveryAgent *q_ptr; + +}; + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_symbian.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_symbian.cpp new file mode 100644 index 00000000..4afd33db --- /dev/null +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_symbian.cpp @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothdevicediscoveryagent_p.h" +#include "qbluetoothaddress.h" + +#include <bttypes.h> + +#include <QDebug> + +QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate() + : inquiryType(QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry) + , lastError(QBluetoothDeviceDiscoveryAgent::NoError) + , errorString(QString()) + , m_deviceDiscovery(0) +{ + /* connect to socker server */ + TInt result = m_socketServer.Connect(); + if (result != KErrNone) + _q_setError(QBluetoothDeviceDiscoveryAgent::UnknownError, + QString("RSocketServ.Connect() failed with error")); +} + +QBluetoothDeviceDiscoveryAgentPrivate::~QBluetoothDeviceDiscoveryAgentPrivate() +{ + delete m_deviceDiscovery; + if (m_socketServer.Handle() != NULL) + m_socketServer.Close(); +} + +void QBluetoothDeviceDiscoveryAgentPrivate::allocate() +{ + Q_Q(QBluetoothDeviceDiscoveryAgent); + // create link manager device discoverer + if (m_socketServer.Handle() != NULL) { + // create new active object for querying devices + m_deviceDiscovery = new BluetoothLinkManagerDeviceDiscoverer(m_socketServer); + if (m_deviceDiscovery) { + QObject::connect(m_deviceDiscovery, SIGNAL(deviceDiscoveryComplete()), q, SIGNAL(finished())); + QObject::connect(m_deviceDiscovery, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo&)), + q, SLOT(_q_newDeviceFound(const QBluetoothDeviceInfo&))); + QObject::connect(m_deviceDiscovery, SIGNAL(linkManagerError(QBluetoothDeviceDiscoveryAgent::Error,QString)), + q, SLOT(_q_setError(QBluetoothDeviceDiscoveryAgent::Error,QString))); + QObject::connect(m_deviceDiscovery, SIGNAL(canceled()), q, SIGNAL(canceled())); + } else { + _q_setError(QBluetoothDeviceDiscoveryAgent::UnknownError, + QString("Cannot allocate BluetoothLinkManagerDeviceDiscoverer: failed with error")); + } + } +} + +void QBluetoothDeviceDiscoveryAgentPrivate::start() +{ + + // clear list of found devices + discoveredDevices.clear(); + if (!m_deviceDiscovery) { + allocate(); + } + m_deviceDiscovery->startDiscovery(inquiryTypeToIAC()); + +} + +void QBluetoothDeviceDiscoveryAgentPrivate::stop() +{ + if (m_deviceDiscovery) + m_deviceDiscovery->stopDiscovery(); +} + +bool QBluetoothDeviceDiscoveryAgentPrivate::isActive() const +{ + if (m_deviceDiscovery) + return m_deviceDiscovery->isReallyActive(); + return false; +} + +void QBluetoothDeviceDiscoveryAgentPrivate::_q_setError(QBluetoothDeviceDiscoveryAgent::Error errorCode, + QString errorDescription) +{ + qDebug() << __PRETTY_FUNCTION__ << errorCode << errorDescription; + if (errorCode == KErrNone) + return; + + Q_Q(QBluetoothDeviceDiscoveryAgent); + + errorString = errorDescription; + emit q->error(errorCode); +} + +void QBluetoothDeviceDiscoveryAgentPrivate::_q_newDeviceFound(const QBluetoothDeviceInfo &device) +{ + // add found device to the list of devices + discoveredDevices.append(device); + Q_Q(QBluetoothDeviceDiscoveryAgent); + emit q->deviceDiscovered(device); +} + +uint QBluetoothDeviceDiscoveryAgentPrivate::inquiryTypeToIAC() const +{ + return inquiryType == QBluetoothDeviceDiscoveryAgent::LimitedInquiry ? KLIAC : KGIAC; +} diff --git a/src/bluetooth/qbluetoothdeviceinfo.cpp b/src/bluetooth/qbluetoothdeviceinfo.cpp new file mode 100644 index 00000000..4f3ee079 --- /dev/null +++ b/src/bluetooth/qbluetoothdeviceinfo.cpp @@ -0,0 +1,529 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothdeviceinfo.h" +#include "qbluetoothdeviceinfo_p.h" + +#include <QDebug> + +/*! + \class QBluetoothDeviceInfo + \brief The QBluetoothDeviceInfo class provides information about Bluetooth devices. + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity + \since 5.0 + + QBluetoothDeviceInfo provides information about a Bluetooth device's name, address and class of device. +*/ + +/*! + \enum QBluetoothDeviceInfo::MajorDeviceClass + + This enum describes a Bluetooth device's major device class. + + \value MiscellaneousDevice A miscellaneous device. + \value ComputerDevice A computer device or PDA. + \value PhoneDevice A telephone device. + \value LANAccessDevice A device that provides access to a local area network. + \value AudioVideoDevice A device capable of playback or capture of audio and/or video. + \value PeripheralDevice A peripheral device such as a keyboard, mouse, etc. + \value ImagingDevice An imaging device such as a display, printer, scanner or camera. + \value WearableDevice A wearable device such as a watch or pager. + \value ToyDevice A toy. + \value HealthDevice A health reated device such as heart rate, or temperature. + \value UncategorizedDevice A device that does not fit into any of the other device classes. +*/ + +/*! + \enum QBluetoothDeviceInfo::MinorMiscellaneousClass + + This enum describes the minor device classes for miscellaneous Bluetooth devices. + + \value UncategorizedMiscellaneous An uncategorized miscellaneous device. +*/ + +/*! + \enum QBluetoothDeviceInfo::MinorComputerClass + + This enum describes the minor device classes for computer devices. + + \value UncategorizedComputer An uncategorized computer device. + \value DesktopComputer A desktop computer. + \value ServerComputer A server computer. + \value LaptopComputer A laptop computer. + \value HandheldClamShellComputer A clamshell handheld computer or PDA. + \value HandheldComputer A handheld computer or PDA. + \value WearableComputer A wearable computer. +*/ + +/*! + \enum QBluetoothDeviceInfo::MinorPhoneClass + + This enum describes the minor device classes for phone devices. + + \value UncategorizedPhone An uncategorized phone device. + \value CellularPhone A cellular phone. + \value CordlessPhone A cordless phone. + \value SmartPhone A smart phone. + \value WiredModemOrVoiceGatewayPhone A wired modem or voice gateway. + \value CommonIsdnAccessPhone A device that provides ISDN access. +*/ + +/*! + \enum QBluetoothDeviceInfo::MinorNetworkClass + + This enum describes the minor device classes for local area network access devices. Local area + network access devices use the minor device class to specify the current network utilization. + + \value NetworkFullService 100% of the total bandwidth is available. + \value NetworkLoadFactorOne 0 - 17% of the total bandwidth is currently being used. + \value NetworkLoadFactorTwo 17 - 33% of the total bandwidth is currently being used. + \value NetworkLoadFactorThree 33 - 50% of the total bandwidth is currently being used. + \value NetworkLoadFactorFour 50 - 67% of the total bandwidth is currently being used. + \value NetworkLoadFactorFive 67 - 83% of the total bandwidth is currently being used. + \value NetworkLoadFactorSix 83 - 99% of the total bandwidth is currently being used. + \value NetworkNoService No network service available. +*/ + +/*! + \enum QBluetoothDeviceInfo::MinorAudioVideoClass + + This enum describes the minor device classes for audio/video devices. + + \value UncategorizedAudioVideoDevice An uncategorized audio/video device. + \value WearableHeadsetDevice A wearable headset device. + \value HandsFreeDevice A hands free device. + \value Microphone A microphone. + \value Loudspeaker A loudspeaker. + \value Headphones Headphones. + \value PortableAudioDevice A portable audio device. + \value CarAudio A car audio device. + \value SetTopBox A set top box. + \value HiFiAudioDevice A HiFi audio device. + \value Vcr A video cassette recorder. + \value VideoCamera A video camera. + \value Camcorder A video camera. + \value VideoMonitor A video monitor. + \value VideoDisplayAndLoudspeaker A video display with built-in loudspeaker. + \value VideoConferencing A video conferencing device. + \value GamingDevice A gaming device. +*/ + +/*! + \enum QBluetoothDeviceInfo::MinorPeripheralClass + + This enum describes the minor device classes for peripheral devices. + + \value UncategorizedPeripheral An uncategorized peripheral device. + \value KeyboardPeripheral A keyboard. + \value PointingDevicePeripheral A pointing device, for example a mouse. + \value KeyboardWithPointingDevicePeripheral A keyboard with built-in pointing device. + \value JoystickPeripheral A joystick. + \value GamepadPeripheral A game pad. + \value RemoteControlPeripheral A remote control. + \value SensingDevicePeripheral A sensing device. + \value DigitizerTabletPeripheral A digitizer tablet peripheral. + \value CardReaderPeripheral A card reader peripheral. +*/ + +/*! + \enum QBluetoothDeviceInfo::MinorImagingClass + + This enum describes the minor device classes for imaging devices. + + \value UncategorizedImagingDevice An uncategorized imaging device. + \value ImageDisplay A device capable of displaying images. + \value ImageCamera A camera. + \value ImageScanner An image scanner. + \value ImagePrinter A printer. +*/ + +/*! + \enum QBluetoothDeviceInfo::MinorWearableClass + + This enum describes the minor device classes for wearable devices. + + \value UncategorizedWearableDevice An uncategorized wearable device. + \value WearableWristWatch A wristwatch. + \value WearablePager A pager. + \value WearableJacket A jacket. + \value WearableHelmet A helmet. + \value WearableGlasses A pair of glasses. +*/ + +/*! + \enum QBluetoothDeviceInfo::MinorToyClass + + This enum describes the minor device classes for toy devices. + + \value UncategorizedToy An uncategorized toy. + \value ToyRobot A toy robot. + \value ToyVehicle A toy vehicle. + \value ToyDoll A toy doll or action figure. + \value ToyController A controller. + \value ToyGame A game. +*/ + +/*! + \enum QBluetoothDeviceInfo::MinorHealthClass + + This enum describes the minor device classes for health devices. + + \value UncategorizedHealthDevice An uncategorized health device. + \value HealthBloodPressureMonitor A blood pressure monitor. + \value HealthThermometer A Thermometer. + \value HealthWeightScale A scale. + \value HealthGlucoseMeter A glucose meter. + \value HealthPulseOximeter A blood oxygen saturation meter. + \value HealthDataDisplay A data display. + \value HealthStepCounter A pedometer. +*/ + + +/*! + \enum QBluetoothDeviceInfo::ServiceClass + + This enum describes the service class of the Bluetooth device. The service class is used as a + rudimentary form of service discovery. It is meant to provide a rudimentary list of the types + of services that the device might provide. + + \value NoService The device does not provide any services. + \value PositioningService The device provides positioning services. + \value NetworkingService The device provides networking services. + \value RenderingService The device provides rendering services. + \value CapturingService The device provides capturing services. + \value ObjectTransferService The device provides object transfer services. + \value AudioService The device provides audio services. + \value TelephonyService The device provides telephony services. + \value InformationService The device provides information services. + \value AllServices The device provides services of all types. +*/ + +/*! + \enum QBluetoothDeviceInfo::DataCompleteness + + This enum describes the completeness of the received data. + + \value DataComplete The data is complete. + \value DataIncomplete The data is incomplete. Addition datum is available via other + interfaces. + \value DataUnavailable No data is available. +*/ + +QBluetoothDeviceInfoPrivate::QBluetoothDeviceInfoPrivate() + : valid(false), cached(false), rssi(1), + serviceClasses(QBluetoothDeviceInfo::NoService), + majorDeviceClass(QBluetoothDeviceInfo::MiscellaneousDevice), + minorDeviceClass(0), + serviceUuidsCompleteness(QBluetoothDeviceInfo::DataUnavailable) +{ +} + +/*! + Constructs an invalid QBluetoothDeviceInfo object. +*/ +QBluetoothDeviceInfo::QBluetoothDeviceInfo() +: d_ptr(new QBluetoothDeviceInfoPrivate) +{ +} + +/*! + Constructs a QBluetoothDeviceInfo object with Bluetooth address \a address, device name + \a name and the encoded class of device \a classOfDevice. + + The \a classOfDevice parameter is encoded in the following format + + \table + \header \o Bits \o Size \o Description + \row \o 0 - 1 \o 2 \o Unused, set to 0. + \row \o 2 - 7 \o 6 \o Minor device class. + \row \o 8 - 12 \o 5 \o Major device class. + \row \o 13 - 23 \o 11 \o Service class. + \endtable +*/ +QBluetoothDeviceInfo::QBluetoothDeviceInfo(const QBluetoothAddress &address, const QString &name, quint32 classOfDevice) +: d_ptr(new QBluetoothDeviceInfoPrivate) +{ + Q_D(QBluetoothDeviceInfo); + + d->address = address; + d->name = name; + + d->minorDeviceClass = static_cast<quint8>((classOfDevice >> 2) & 0x3f); + d->majorDeviceClass = static_cast<MajorDeviceClass>((classOfDevice >> 8) & 0x1f); + d->serviceClasses = static_cast<ServiceClasses>((classOfDevice >> 13) & 0x7ff); + + d->serviceUuidsCompleteness = DataUnavailable; + + d->valid = true; + d->cached = false; + d->rssi = 0; +} + +/*! + Constructs a QBluetoothDeviceInfo that is a copy of \a other. +*/ +QBluetoothDeviceInfo::QBluetoothDeviceInfo(const QBluetoothDeviceInfo &other) +: d_ptr(new QBluetoothDeviceInfoPrivate) +{ + *this = other; +} + +/*! + Destroys the QBluetoothDeviceInfo. +*/ +QBluetoothDeviceInfo::~QBluetoothDeviceInfo() +{ + delete d_ptr; +} + +/*! + Returns true if the QBluetoothDeviceInfo object is valid, otherwise returns false. +*/ +bool QBluetoothDeviceInfo::isValid() const +{ + Q_D(const QBluetoothDeviceInfo); + + return d->valid; +} +/*! + Returns the signal strength when the device was last scanned + */ +qint16 QBluetoothDeviceInfo::rssi() const +{ + Q_D(const QBluetoothDeviceInfo); + + return d->rssi; +} + +/*! + Set the \a signal strength value, used internally. + */ +void QBluetoothDeviceInfo::setRssi(qint16 signal) +{ + Q_D(QBluetoothDeviceInfo); + d->rssi = signal; +} + +/*! + Makes a copy of the \a other and assigns it to this QBluetoothDeviceInfo object. +*/ +QBluetoothDeviceInfo &QBluetoothDeviceInfo::operator=(const QBluetoothDeviceInfo &other) +{ + Q_D(QBluetoothDeviceInfo); + + d->address = other.d_func()->address; + d->name = other.d_func()->name; + d->minorDeviceClass = other.d_func()->minorDeviceClass; + d->majorDeviceClass = other.d_func()->majorDeviceClass; + d->serviceClasses = other.d_func()->serviceClasses; + d->valid = other.d_func()->valid; + d->cached = other.d_func()->cached; + d->serviceUuidsCompleteness = other.d_func()->serviceUuidsCompleteness; + d->serviceUuids = other.d_func()->serviceUuids; + d->rssi = other.d_func()->rssi; + + return *this; +} + +/*! + Returns true if the \a other QBluetoothDeviceInfo object and this are identical + */ +bool QBluetoothDeviceInfo::operator==(const QBluetoothDeviceInfo &other) const +{ + Q_D(const QBluetoothDeviceInfo); + + if(d->cached != other.d_func()->cached) + return false; + if(d->valid != other.d_func()->valid) + return false; + if(d->majorDeviceClass != other.d_func()->majorDeviceClass) + return false; + if(d->minorDeviceClass != other.d_func()->minorDeviceClass) + return false; + if(d->serviceClasses != other.d_func()->serviceClasses) + return false; + if(d->name != other.d_func()->name) + return false; + if(d->address != other.d_func()->address) + return false; + if(d->serviceUuidsCompleteness != other.d_func()->serviceUuidsCompleteness) + return false; + if(d->serviceUuids.count() != other.d_func()->serviceUuids.count()) + return false; + if(d->serviceUuids != other.d_func()->serviceUuids) + return false; + + return true; + +} + +/*! + Returns the address of the device. +*/ +QBluetoothAddress QBluetoothDeviceInfo::address() const +{ + Q_D(const QBluetoothDeviceInfo); + + return d->address; +} + +/*! + Returns the name assigned to the device. +*/ +QString QBluetoothDeviceInfo::name() const +{ + Q_D(const QBluetoothDeviceInfo); + + return d->name; +} + +/*! + Returns the service class of the device. +*/ +QBluetoothDeviceInfo::ServiceClasses QBluetoothDeviceInfo::serviceClasses() const +{ + Q_D(const QBluetoothDeviceInfo); + + return d->serviceClasses; +} + +/*! + Returns the major device class of the device. +*/ +QBluetoothDeviceInfo::MajorDeviceClass QBluetoothDeviceInfo::majorDeviceClass() const +{ + Q_D(const QBluetoothDeviceInfo); + + return d->majorDeviceClass; +} + +/*! + Returns the minor device class of the device. +*/ +quint8 QBluetoothDeviceInfo::minorDeviceClass() const +{ + Q_D(const QBluetoothDeviceInfo); + + return d->minorDeviceClass; +} + +/*! + Sets the list of service UUIDs to \a uuids and the completeness of the data to \a completeness. +*/ +void QBluetoothDeviceInfo::setServiceUuids(const QList<QBluetoothUuid> &uuids, DataCompleteness completeness) +{ + Q_D(QBluetoothDeviceInfo); + + d->serviceUuids = uuids; + d->serviceUuidsCompleteness = completeness; +} + +/*! + Returns the list of service UUIDS supported by the device. If \a completeness is not 0 it will + be set to DataComplete if the returned list is the complete list of UUIDs supported by the + device. DataIncomplete if additional service UUIDs are supported by the device and + DataUnavailable if no service UUID information is available. + + This function requires both Bluetooth devices to support the 2.1 specification. +*/ +QList<QBluetoothUuid> QBluetoothDeviceInfo::serviceUuids(DataCompleteness *completeness) const +{ + Q_D(const QBluetoothDeviceInfo); + + if (completeness) + *completeness = d->serviceUuidsCompleteness; + + return d->serviceUuids; +} + +/*! + Returns the completeness of the service UUID list. If DataComplete is returned then + serviceUuids() will return a complete list of service UUIDs supported by the device. Otherwise + serviceUuids() will only return a partial or empty list of service UUIDs. To get a full list + of services supported by the device a full service discovery needs to be performed. +*/ +QBluetoothDeviceInfo::DataCompleteness QBluetoothDeviceInfo::serviceUuidsCompleteness() const +{ + Q_D(const QBluetoothDeviceInfo); + + return d->serviceUuidsCompleteness; +} + +/*! + Sets the manufacturer specific data returned by Extended Inquiry Responses to \a data. +*/ +void QBluetoothDeviceInfo::setManufacturerSpecificData(const QByteArray &data) +{ + Q_UNUSED(data); +} + +/*! + Returns the manufacturer specific data. If \a available is not 0 it is set to true if + manufacturer specific data is available; otherwise it is set to false. +*/ +QByteArray QBluetoothDeviceInfo::manufacturerSpecificData(bool *available) const +{ + Q_UNUSED(available); + return QByteArray(); +} + +/*! + Returns true if the QBluetoothDeviceInfo object is created from cached data +*/ +bool QBluetoothDeviceInfo::isCached() const +{ + Q_D(const QBluetoothDeviceInfo); + + return d->cached; +} + +/*! + Used by the system to set the \a cached flag if the QBluetoothDeviceInfo is created from cached data. Cached information + may not be as accurate as data read from a live device. + */ +void QBluetoothDeviceInfo::setCached(bool cached) +{ + Q_D(QBluetoothDeviceInfo); + + d->cached = cached; +} diff --git a/src/bluetooth/qbluetoothdeviceinfo.h b/src/bluetooth/qbluetoothdeviceinfo.h new file mode 100644 index 00000000..2dc6212f --- /dev/null +++ b/src/bluetooth/qbluetoothdeviceinfo.h @@ -0,0 +1,245 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHDEVICEINFO_H +#define QBLUETOOTHDEVICEINFO_H + +#include "../qtconnectivityglobal.h" + +#include <QString> + +QT_BEGIN_HEADER + +class QBluetoothDeviceInfoPrivate; +class QBluetoothAddress; +class QBluetoothUuid; + +class Q_CONNECTIVITY_EXPORT QBluetoothDeviceInfo +{ +public: + enum MajorDeviceClass { + MiscellaneousDevice = 0, + ComputerDevice = 1, + PhoneDevice = 2, + LANAccessDevice = 3, + AudioVideoDevice = 4, + PeripheralDevice = 5, + ImagingDevice = 6, + WearableDevice = 7, + ToyDevice = 8, + HealthDevice = 9, + UncategorizedDevice = 31, + }; + + enum MinorMiscellaneousClass { + UncategorizedMiscellaneous = 0, + }; + + enum MinorComputerClass { + UncategorizedComputer = 0, + DesktopComputer = 1, + ServerComputer = 2, + LaptopComputer = 3, + HandheldClamShellComputer = 4, + HandheldComputer = 5, + WearableComputer = 6, + }; + + enum MinorPhoneClass { + UncategorizedPhone = 0, + CellularPhone = 1, + CordlessPhone = 2, + SmartPhone = 3, + WiredModemOrVoiceGatewayPhone = 4, + CommonIsdnAccessPhone = 5, + }; + + enum MinorNetworkClass { + NetworkFullService = 0x00, + NetworkLoadFactorOne = 0x08, + NetworkLoadFactorTwo = 0x10, + NetworkLoadFactorThree = 0x18, + NetworkLoadFactorFour = 0x20, + NetworkLoadFactorFive = 0x28, + NetworkLoadFactorSix = 0x30, + NetworkNoService = 0x38, + }; + + enum MinorAudioVideoClass { + UncategorizedAudioVideoDevice = 0, + WearableHeadsetDevice = 1, + HandsFreeDevice = 2, + // reserved = 3, + Microphone = 4, + Loudspeaker = 5, + Headphones = 6, + PortableAudioDevice = 7, + CarAudio = 8, + SetTopBox = 9, + HiFiAudioDevice = 10, + Vcr = 11, + VideoCamera = 12, + Camcorder = 13, + VideoMonitor = 14, + VideoDisplayAndLoudspeaker = 15, + VideoConferencing = 16, + // reserved = 17, + GamingDevice = 18, + }; + + enum MinorPeripheralClass { + UncategorizedPeripheral = 0, + KeyboardPeripheral = 0x10, + PointingDevicePeripheral = 0x20, + KeyboardWithPointingDevicePeripheral = 0x30, + + JoystickPeripheral = 0x01, + GamepadPeripheral = 0x02, + RemoteControlPeripheral = 0x03, + SensingDevicePeripheral = 0x04, + DigitizerTabletPeripheral = 0x05, + CardReaderPeripheral = 0x06, + }; + + enum MinorImagingClass { + UncategorizedImagingDevice = 0, + ImageDisplay = 0x04, + ImageCamera = 0x08, + ImageScanner = 0x10, + ImagePrinter = 0x20 + }; + + enum MinorWearableClass { + UncategorizedWearableDevice = 0, + WearableWristWatch = 1, + WearablePager = 2, + WearableJacket = 3, + WearableHelmet = 4, + WearableGlasses = 5, + }; + + enum MinorToyClass { + UncategorizedToy = 0, + ToyRobot = 1, + ToyVehicle = 2, + ToyDoll = 3, + ToyController = 4, + ToyGame = 5, + }; + + enum MinorHealthClass { + UncategorizedHealthDevice = 0, + HealthBloodPressureMonitor = 0x1, + HealthThermometer = 0x2, + HealthWeightScale = 0x3, + HealthGlucoseMeter = 0x4, + HealthPulseOximeter = 0x5, + HealthDataDisplay = 0x7, + HealthStepCounter = 0x8 + }; + + enum ServiceClass { + NoService = 0x0000, + PositioningService = 0x0001, + NetworkingService = 0x0002, + RenderingService = 0x0004, + CapturingService = 0x0008, + ObjectTransferService = 0x0010, + AudioService = 0x0020, + TelephonyService = 0x0040, + InformationService = 0x0080, + AllServices = 0x07ff, + }; + Q_DECLARE_FLAGS(ServiceClasses, ServiceClass) + + enum DataCompleteness { + DataComplete, + DataIncomplete, + DataUnavailable, + }; + + QBluetoothDeviceInfo(); + QBluetoothDeviceInfo(const QBluetoothAddress &address, const QString &name, quint32 classOfDevice); + QBluetoothDeviceInfo(const QBluetoothDeviceInfo &other); + ~QBluetoothDeviceInfo(); + + bool isValid() const; + bool isCached() const; + + void setCached(bool cached); + + QBluetoothDeviceInfo &operator=(const QBluetoothDeviceInfo &other); + bool operator==(const QBluetoothDeviceInfo &other) const; + + QBluetoothAddress address() const; + QString name() const; + + ServiceClasses serviceClasses() const; + MajorDeviceClass majorDeviceClass() const; + quint8 minorDeviceClass() const; + + qint16 rssi() const; + void setRssi(qint16 signal); + +// bool matchesMinorClass(MinorComputerClass minor) const; +// bool matchesMinorClass(MinorPhoneClass minor) const; +// bool matchesMinorClass(MinorNetworkClass minor) const; +// bool matchesMinorClass(MinorAudioVideoClass minor) const; +// bool matchesMinorClass(MinorPeripheralClass minor) const; +// bool matchesMinorClass(MinorImagingClass minor) const; + + void setServiceUuids(const QList<QBluetoothUuid> &uuids, DataCompleteness completeness); + QList<QBluetoothUuid> serviceUuids(DataCompleteness *completeness = 0) const; + DataCompleteness serviceUuidsCompleteness() const; + + void setManufacturerSpecificData(const QByteArray &data); + QByteArray manufacturerSpecificData(bool *available = 0) const; + +protected: + QBluetoothDeviceInfoPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QBluetoothDeviceInfo) +}; + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/qbluetoothdeviceinfo_p.h b/src/bluetooth/qbluetoothdeviceinfo_p.h new file mode 100644 index 00000000..21864741 --- /dev/null +++ b/src/bluetooth/qbluetoothdeviceinfo_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHDEVICEINFO_P_H +#define QBLUETOOTHDEVICEINFO_P_H + +#include "qbluetoothdeviceinfo.h" +#include "qbluetoothaddress.h" +#include "qbluetoothuuid.h" + +#include <QString> + +QT_BEGIN_HEADER + +class QBluetoothDeviceInfoPrivate +{ +public: + QBluetoothDeviceInfoPrivate(); + + bool valid; + bool cached; + + QBluetoothAddress address; + QString name; + + qint16 rssi; + + QBluetoothDeviceInfo::ServiceClasses serviceClasses; + QBluetoothDeviceInfo::MajorDeviceClass majorDeviceClass; + quint8 minorDeviceClass; + + QBluetoothDeviceInfo::DataCompleteness serviceUuidsCompleteness; + QList<QBluetoothUuid> serviceUuids; +}; + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/qbluetoothlocaldevice.cpp b/src/bluetooth/qbluetoothlocaldevice.cpp new file mode 100644 index 00000000..8cba00e7 --- /dev/null +++ b/src/bluetooth/qbluetoothlocaldevice.cpp @@ -0,0 +1,239 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothlocaldevice.h" +#include "qbluetoothlocaldevice_p.h" +#include "qbluetoothaddress.h" + +#include <QtCore/QString> +#include <QDebug> + +/*! + \class QBluetoothLocalDevice + \brief The QBluetoothLocalDevice class provides access to local Bluetooth devices. + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity + \since 5.0 + + QBluetoothLocalDevice provides functions for getting and setting the state of local Bluetooth + devices. +*/ + +/*! + \enum QBluetoothLocalDevice::Pairing + + This enum describes the pairing state between two Bluetooth devices. + + \value Unpaired The Bluetooth devices are not paired. + \value Paired The Bluetooth devices are paired. The system will prompt the user for + authorization when the remote device initiates a connection to the + local device. + \value AuthorizedPaired The Bluetooth devices are paired. The system will not prompt the user + for authorization when the remote device initiates a connection to the + local device. +*/ + +/*! + \enum QBluetoothLocalDevice::Error + + This enum describes errors that maybe returned + + \value NoError No known error + \value PairingError Error in pairing + \value UnknownError Unknown error + +*/ + +/*! + \enum QBluetoothLocalDevice::HostMode + + This enum describes the most of the local Bluetooth device. + + \value HostPoweredOff Powers the device down + \value HostConnectable Remote Bluetooth devices can connect to the local Bluetooth device + if they have previously been paired with it or otherwise know its + address. This powers up the device if it was powered off. + \value HostDiscoverable Remote Bluetooth devices can discover the presence of the local + Bluetooth device. The device will also be connectable, and powered on. + \value HostDiscoverableLimitedInquiry Remote Bluetooth devices can discover the presence of the local + Bluetooth device when performing a limited inquiry. This should be used for + locating services that are only made discoverable for a limited period of time. + This can speed up discovery between games for example, since service + discovery can be skipped on devices not in limited enquiry more. This + is not supported on all platforms. The device will also be connectable, and powered on. + +*/ + +namespace +{ +class LocalDeviceRegisterMetaTypes +{ +public: + LocalDeviceRegisterMetaTypes() + { + qRegisterMetaType<QBluetoothLocalDevice::HostMode>("QBluetoothLocalDevice::HostMode"); + qRegisterMetaType<QBluetoothLocalDevice::Pairing>("QBluetoothLocalDevice::Pairing"); + qRegisterMetaType<QBluetoothLocalDevice::Error>("QBluetoothLocalDevice::Error"); + } +} _registerLocalDeviceMetaTypes; +} + +/*! + Destroys the QBluetoothLocalDevice. +*/ +QBluetoothLocalDevice::~QBluetoothLocalDevice() +{ + delete d_ptr; +} + +/*! + Returns true the QBluetoothLocalDevice represents an available local Bluetooth device; + otherwise return false. +*/ +bool QBluetoothLocalDevice::isValid() const +{ + return d_ptr; +} + +/*! + \fn void QBluetoothLocalDevice::setHostMode(QBluetoothLocalDevice::HostMode mode) + + Sets the host mode the this local Bluetooth device to \a mode. +*/ + +/*! + \fn QBluetoothLocalDevice::HostMode QBluetoothLocalDevice::hostMode() const + + Returns the current host mode of this local Bluetooth device. +*/ + +/*! + \fn QBluetoothLocalDevice::name() const + + Returns the name assgined by the user to this Bluetooth device. +*/ + +/*! + \fn QBluetoothLocalDevice::address() const + + Returns the MAC address of this Bluetooth device. +*/ + +/*! + \fn QList<QBluetoothLocalDevice> QBluetoothLocalDevice::allDevices() + + Returns a list of all available local Bluetooth devices. +*/ + +/*! + \fn QBluetoothLocalDevice::powerOn() + + Powers on the device on returning it to the hostMode() state is was in when powered down +*/ + +/*! + \fn QBluetoothLocalDevice::QBluetoothLocalDevice(QObject *parent) + Constructs a QBluetoothLocalDevice with \a parent. +*/ + +/*! + \fn QBluetoothLocalDevice::hostModeStateChanged(QBluetoothLocalDevice::HostMode state) + The \a state of the host has transitioned to a different HostMode +*/ + +/*! + \fn QBluetoothLocalDevice::pairingStatus(const QBluetoothAddress &address) const + + Returns the current bluetooth pairing status of \a address, if it's unpaired, paired, or paired and authorized. +*/ + + +/*! + \fn QBluetoothLocalDevice::pairingDisplayConfirmation(const QBluetoothAddress &address, QString pin) + + Signal by some platforms to display a pairing confirmation dialog for \a address. The user + is asked to confirm the \a pin is the same on both devices. QBluetoothLocalDevice::pairingConfirmation(bool) + must be called to indicate if the user accepts or rejects the displayed pin. +*/ + +/*! + \fn QBluetoothLocalDevice::pairingConfirmation(bool accept) + + To be called after getting a pairingDisplayConfirmation(). The \a accept parameter either + accepts the pairing or rejects it. +*/ + +/*! + \fn QBluetoothLocalDevice::pairingDisplayPinCode(const QBluetoothAddress &address, QString pin) + + Signal by some platforms to display the \a pin to the user for \a address. The pin is automatically + generated, and does not need to be confirmed. +*/ + +/*! + \fn QBluetoothLocalDevice::requestPairing(const QBluetoothAddress &address, Pairing pairing) + + Set the \a pairing status with \a address. The results are returned via + the signal pairingFinished(). Caution: creating a pairing may take minutes, and can require + the user to acknowledge dialogs. +*/ + +/*! + \fn QBluetoothLocalDevice::pairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing) + + Pairing has completed with \a address. Current pairing status is in \a pairing. +*/ + +/*! + \fn QBluetoothLocalDevice::error(QBluetoothLocalDevice::Error error) + Signal emitted for pairing if there's an exceptional \a error +*/ + + +/*! + \fn QBluetoothLocalDevice::QBluetoothLocalDevice(const QBluetoothAddress &address, QObject *parent = 0) + + Construct new QBluetoothLocalDevice for \a address. +*/ + + +#include "moc_qbluetoothlocaldevice.cpp" diff --git a/src/bluetooth/qbluetoothlocaldevice.h b/src/bluetooth/qbluetoothlocaldevice.h new file mode 100644 index 00000000..41530819 --- /dev/null +++ b/src/bluetooth/qbluetoothlocaldevice.h @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef QBLUETOOTHLOCALDEVICE_H +#define QBLUETOOTHLOCALDEVICE_H + +#include "../qtconnectivityglobal.h" + +#include <QObject> +#include <QtCore/QList> +#include <QString> + +#include "qbluetoothaddress.h" + +QT_BEGIN_HEADER + +class QBluetoothLocalDevicePrivate; + +class Q_CONNECTIVITY_EXPORT QBluetoothHostInfo +{ +public: + QBluetoothHostInfo() { }; + QBluetoothHostInfo(const QBluetoothHostInfo &other) { + m_address = other.m_address; + m_name = other.m_name; + }; + + QBluetoothAddress getAddress() const { return m_address; } + void setAddress(const QBluetoothAddress &address) { m_address = address; } + + QString getName() const { return m_name; } + void setName(const QString &name){ m_name = name; } + +private: + QBluetoothAddress m_address; + QString m_name; + +}; + + +class Q_CONNECTIVITY_EXPORT QBluetoothLocalDevice : public QObject +{ + Q_OBJECT + Q_ENUMS(Pairing) + Q_ENUMS(HostMode) + Q_ENUMS(Error) +public: + enum Pairing { + Unpaired, + Paired, + AuthorizedPaired + }; + + enum HostMode { + HostPoweredOff, + HostConnectable, + HostDiscoverable, + HostDiscoverableLimitedInquiry + }; + + enum Error { + NoError, + PairingError, + UnknownError = 100 + }; + QBluetoothLocalDevice(QObject *parent = 0); + explicit QBluetoothLocalDevice(const QBluetoothAddress &address, QObject *parent = 0); + virtual ~QBluetoothLocalDevice(); + + bool isValid() const; + + void requestPairing(const QBluetoothAddress &address, Pairing pairing); + Pairing pairingStatus(const QBluetoothAddress &address) const; + + void setHostMode(QBluetoothLocalDevice::HostMode mode); + HostMode hostMode() const; + + void powerOn(); + + QString name() const; + QBluetoothAddress address() const; + + static QList<QBluetoothHostInfo> allDevices(); + +public Q_SLOTS: + void pairingConfirmation(bool confirmation); + +Q_SIGNALS: + void hostModeStateChanged(QBluetoothLocalDevice::HostMode state); + void pairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing); + + void pairingDisplayPinCode(const QBluetoothAddress &address, QString pin); + void pairingDisplayConfirmation(const QBluetoothAddress &address, QString pin); + void error(QBluetoothLocalDevice::Error error); + +private: + Q_DECLARE_PRIVATE(QBluetoothLocalDevice) + QBluetoothLocalDevicePrivate *d_ptr; +#ifdef QT_SYMBIAN_BLUETOOTH + Q_PRIVATE_SLOT(d_func(), void _q_pairingFinished(const QBluetoothAddress &, QBluetoothLocalDevice::Pairing)) + Q_PRIVATE_SLOT(d_func(), void _q_registryError(int error)) + Q_PRIVATE_SLOT(d_func(), void _q_pairingError(int error)) +#endif //QT_SYMBIAN_BLUETOOTH +}; + +Q_DECLARE_METATYPE(QBluetoothLocalDevice::HostMode) +Q_DECLARE_METATYPE(QBluetoothLocalDevice::Pairing) +Q_DECLARE_METATYPE(QBluetoothLocalDevice::Error) + +QT_END_HEADER + +#endif // QBLUETOOTHLOCALDEVICE_H diff --git a/src/bluetooth/qbluetoothlocaldevice_bluez.cpp b/src/bluetooth/qbluetoothlocaldevice_bluez.cpp new file mode 100644 index 00000000..124a18b0 --- /dev/null +++ b/src/bluetooth/qbluetoothlocaldevice_bluez.cpp @@ -0,0 +1,518 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QDBusContext> + +#include "qbluetoothlocaldevice.h" +#include "qbluetoothaddress.h" +#include "qbluetoothlocaldevice_p.h" + +#include "bluez/manager_p.h" +#include "bluez/adapter_p.h" +#include "bluez/agent_p.h" +#include "bluez/device_p.h" + +static const QLatin1String agentPath("/qt/agent"); + +QBluetoothLocalDevice::QBluetoothLocalDevice(QObject *parent) +: QObject(parent) +{ + OrgBluezManagerInterface manager(QLatin1String("org.bluez"), QLatin1String("/"), + QDBusConnection::systemBus()); + + QDBusPendingReply<QDBusObjectPath> reply = manager.DefaultAdapter(); + reply.waitForFinished(); + if (reply.isError()) + return; + + OrgBluezAdapterInterface *adapter = new OrgBluezAdapterInterface(QLatin1String("org.bluez"), + reply.value().path(), + QDBusConnection::systemBus()); + + this->d_ptr = new QBluetoothLocalDevicePrivate; + this->d_ptr->adapter = adapter; + this->d_ptr->q_ptr = this; + this->d_ptr->agent = 0x0; + this->d_ptr->msgConnection = 0x0; + this->d_ptr->currentMode = static_cast<QBluetoothLocalDevice::HostMode>(-1); + + connect(adapter, SIGNAL(PropertyChanged(QString,QDBusVariant)), + this->d_ptr, SLOT(PropertyChanged(QString,QDBusVariant))); + +// connect(d_ptr, SIGNAL(pairingFinished(const QBluetoothAddress&,QBluetoothLocalDevice::Pairing)), this, SIGNAL(pairingFinished(const QBluetoothAddress&,QBluetoothLocalDevice::Pairing))); +// connect(this->d_ptr, SIGNAL(pairingDisplayPinCode(const QBluetoothAddress &,QString)), +// this, SIGNAL(pairingDisplayPinCode(const QBluetoothAddress &,QString))); + + qsrand(QTime::currentTime().msec()); + this->d_ptr->agent_path = agentPath; + this->d_ptr->agent_path.append(QString::fromLatin1("/%1").arg(qrand())); + +} + +QBluetoothLocalDevice::QBluetoothLocalDevice(const QBluetoothAddress &address, QObject *parent) +: QObject(parent) +{ + OrgBluezManagerInterface manager(QLatin1String("org.bluez"), QLatin1String("/"), + QDBusConnection::systemBus()); + + QDBusPendingReply<QList<QDBusObjectPath> > reply = manager.ListAdapters(); + reply.waitForFinished(); + if (reply.isError()) + return; + + + foreach (const QDBusObjectPath &path, reply.value()) { + OrgBluezAdapterInterface *adapter = new OrgBluezAdapterInterface(QLatin1String("org.bluez"), + path.path(), + QDBusConnection::systemBus()); + + QDBusPendingReply<QVariantMap> reply = adapter->GetProperties(); + reply.waitForFinished(); + if (reply.isError()) + continue; + + QBluetoothAddress path_address(reply.value().value(QLatin1String("Address")).toString()); + + if(path_address == address){ + this->d_ptr = new QBluetoothLocalDevicePrivate; + this->d_ptr->adapter = adapter; + break; + } + else { + delete adapter; + } + } +} + +QString QBluetoothLocalDevice::name() const +{ + if (!d_ptr) + return QString(); + + QDBusPendingReply<QVariantMap> reply = d_ptr->adapter->GetProperties(); + reply.waitForFinished(); + if (reply.isError()) + return QString(); + + return reply.value().value(QLatin1String("Name")).toString(); +} + +QBluetoothAddress QBluetoothLocalDevice::address() const +{ + if (!d_ptr) + return QBluetoothAddress(); + + QDBusPendingReply<QVariantMap> reply = d_ptr->adapter->GetProperties(); + reply.waitForFinished(); + if (reply.isError()) + return QBluetoothAddress(); + + return QBluetoothAddress(reply.value().value(QLatin1String("Address")).toString()); +} + +void QBluetoothLocalDevice::powerOn() +{ + if (!d_ptr) + return; + + d_ptr->adapter->SetProperty(QLatin1String("Powered"), QDBusVariant(QVariant::fromValue(true))); +} + +void QBluetoothLocalDevice::setHostMode(QBluetoothLocalDevice::HostMode mode) +{ + if (!d_ptr) + return; + + switch (mode) { + case HostDiscoverableLimitedInquiry: + case HostDiscoverable: + d_ptr->adapter->SetProperty(QLatin1String("Powered"), QDBusVariant(QVariant::fromValue(true))); + d_ptr->adapter->SetProperty(QLatin1String("Discoverable"), + QDBusVariant(QVariant::fromValue(true))); + break; + case HostConnectable: + d_ptr->adapter->SetProperty(QLatin1String("Powered"), QDBusVariant(QVariant::fromValue(true))); + d_ptr->adapter->SetProperty(QLatin1String("Discoverable"), + QDBusVariant(QVariant::fromValue(false))); + break; + case HostPoweredOff: + d_ptr->adapter->SetProperty(QLatin1String("Powered"), + QDBusVariant(QVariant::fromValue(false))); +// d->adapter->SetProperty(QLatin1String("Discoverable"), +// QDBusVariant(QVariant::fromValue(false))); + break; + } +} + +QBluetoothLocalDevice::HostMode QBluetoothLocalDevice::hostMode() const +{ + if (!d_ptr) + return HostPoweredOff; + + QDBusPendingReply<QVariantMap> reply = d_ptr->adapter->GetProperties(); + reply.waitForFinished(); + if (reply.isError()) + return HostPoweredOff; + + if (!reply.value().value(QLatin1String("Powered")).toBool()) + return HostPoweredOff; + else if (reply.value().value(QLatin1String("Discoverable")).toBool()) + return HostDiscoverable; + else if (reply.value().value(QLatin1String("Powered")).toBool()) + return HostConnectable; + + return HostPoweredOff; +} + +QList<QBluetoothHostInfo> QBluetoothLocalDevice::allDevices() +{ + QList<QBluetoothHostInfo> localDevices; + + OrgBluezManagerInterface manager(QLatin1String("org.bluez"), QLatin1String("/"), + QDBusConnection::systemBus()); + + QDBusPendingReply<QList<QDBusObjectPath> > reply = manager.ListAdapters(); + reply.waitForFinished(); + if (reply.isError()) + return localDevices; + + + foreach (const QDBusObjectPath &path, reply.value()) { + QBluetoothHostInfo hostinfo; + OrgBluezAdapterInterface adapter(QLatin1String("org.bluez"), path.path(), + QDBusConnection::systemBus()); + + QDBusPendingReply<QVariantMap> reply = adapter.GetProperties(); + reply.waitForFinished(); + if (reply.isError()) + continue; + + hostinfo.setAddress(QBluetoothAddress(reply.value().value(QLatin1String("Address")).toString())); + hostinfo.setName(reply.value().value(QLatin1String("Name")).toString()); + + localDevices.append(hostinfo); + } + + return localDevices; +} + +static inline OrgBluezDeviceInterface *getDevice(const QBluetoothAddress &address, QBluetoothLocalDevicePrivate *d_ptr){ + QDBusPendingReply<QDBusObjectPath> reply = d_ptr->adapter->FindDevice(address.toString()); + reply.waitForFinished(); + if(reply.isError()){ + qDebug() << Q_FUNC_INFO << "reply failed" << reply.error(); + return 0; + } + + QDBusObjectPath path = reply.value(); + + return new OrgBluezDeviceInterface(QLatin1String("org.bluez"), path.path(), + QDBusConnection::systemBus()); +} + +void QBluetoothLocalDevice::requestPairing(const QBluetoothAddress &address, Pairing pairing) +{ + + if(pairing == Paired || pairing == AuthorizedPaired) { + + d_ptr->address = address; + d_ptr->pairing = pairing; + + if(!d_ptr->agent){ + d_ptr->agent = new OrgBluezAgentAdaptor(d_ptr); + bool res = QDBusConnection::systemBus().registerObject(d_ptr->agent_path, d_ptr); + if(!res){ + qDebug() << "Failed to register agent"; + return; + } + } + + Pairing current_pairing = pairingStatus(address); + if(current_pairing == Paired && pairing == AuthorizedPaired){ + OrgBluezDeviceInterface *device = getDevice(address, d_ptr); + if(!device) + return; + QDBusPendingReply<> deviceReply = device->SetProperty(QLatin1String("Trusted"), QDBusVariant(true)); + deviceReply.waitForFinished(); + if(deviceReply.isError()){ + qDebug() << Q_FUNC_INFO << "reply failed" << deviceReply.error(); + return; + } + delete device; + QMetaObject::invokeMethod(this, "pairingFinished", Qt::QueuedConnection, Q_ARG(QBluetoothAddress, address), + Q_ARG(QBluetoothLocalDevice::Pairing, QBluetoothLocalDevice::AuthorizedPaired)); + } + else if(current_pairing == AuthorizedPaired && pairing == Paired){ + OrgBluezDeviceInterface *device = getDevice(address, d_ptr); + if(!device) + return; + QDBusPendingReply<> deviceReply = device->SetProperty(QLatin1String("Trusted"), QDBusVariant(false)); + deviceReply.waitForFinished(); + if(deviceReply.isError()){ + qDebug() << Q_FUNC_INFO << "reply failed" << deviceReply.error(); + return; + } + delete device; + QMetaObject::invokeMethod(this, "pairingFinished", Qt::QueuedConnection, Q_ARG(QBluetoothAddress, address), + Q_ARG(QBluetoothLocalDevice::Pairing, QBluetoothLocalDevice::Paired)); + } + else { + QDBusPendingReply<QDBusObjectPath> reply = + d_ptr->adapter->CreatePairedDevice(address.toString(), + QDBusObjectPath(d_ptr->agent_path), + QLatin1String("NoInputNoOutput")); + + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), d_ptr, SLOT(pairingCompleted(QDBusPendingCallWatcher*))); + + if(reply.isError()) + qDebug() << Q_FUNC_INFO << reply.error() << d_ptr->agent_path; + } + } + else if(pairing == Unpaired) { + QDBusPendingReply<QDBusObjectPath> reply = this->d_ptr->adapter->FindDevice(address.toString()); + reply.waitForFinished(); + if(reply.isError()) { + qDebug() << Q_FUNC_INFO << "failed to find device" << reply.error(); + return; + } + QDBusPendingReply<> removeReply = this->d_ptr->adapter->RemoveDevice(reply.value()); + removeReply.waitForFinished(); + if(removeReply.isError()){ + qDebug() << Q_FUNC_INFO << "failed to remove device" << removeReply.error(); + } + return; + } + return; +} + +QBluetoothLocalDevice::Pairing QBluetoothLocalDevice::pairingStatus(const QBluetoothAddress &address) const +{ + OrgBluezDeviceInterface *device = getDevice(address, d_ptr); + + if(!device) + return Unpaired; + + QDBusPendingReply<QVariantMap> deviceReply = device->GetProperties(); + deviceReply.waitForFinished(); + if (deviceReply.isError()) + return Unpaired; + + QVariantMap map = deviceReply.value(); + +// qDebug() << "Paired: " << map.value("Paired"); + + + if (map.value(QLatin1String("Trusted")).toBool() && map.value(QLatin1String("Paired")).toBool()) + return AuthorizedPaired; + else if (map.value(QLatin1String("Paired")).toBool()) + return Paired; + else + return Unpaired; + +} + +QBluetoothLocalDevicePrivate::QBluetoothLocalDevicePrivate() + : adapter(0), agent(0), msgConnection(0) +{ + +} + +QBluetoothLocalDevicePrivate::~QBluetoothLocalDevicePrivate() +{ + delete msgConnection; + delete adapter; + delete agent; +} + +void QBluetoothLocalDevicePrivate::RequestConfirmation(const QDBusObjectPath &in0, uint in1) +{ + Q_UNUSED(in0); + Q_Q(QBluetoothLocalDevice); + setDelayedReply(true); + msgConfirmation = message(); + msgConnection = new QDBusConnection(connection()); + emit q->pairingDisplayConfirmation(address, QString::fromLatin1("%1").arg(in1)); + return; +} + +void QBluetoothLocalDevice::pairingConfirmation(bool confirmation) +{ + if(!d_ptr || + !d_ptr->msgConfirmation.isReplyRequired() || + !d_ptr->msgConnection) + return; + + if(confirmation){ + QDBusMessage msg = d_ptr->msgConfirmation.createReply(QVariant(true)); + d_ptr->msgConnection->send(msg); + } + else { + QDBusMessage error = + d_ptr->msgConfirmation.createErrorReply(QDBusError::AccessDenied, + QLatin1String("Pairing rejected")); + d_ptr->msgConnection->send(error); + } + delete d_ptr->msgConnection; + d_ptr->msgConnection = 0; +} + +QString QBluetoothLocalDevicePrivate::RequestPinCode(const QDBusObjectPath &in0) +{ + Q_Q(QBluetoothLocalDevice); + qDebug() << Q_FUNC_INFO << in0.path(); + // seeded in constructor, 6 digit pin + QString pin = QString::fromLatin1("%1").arg(qrand()&1000000); + pin = QString::fromLatin1("%1").arg(pin, 6, QLatin1Char('0')); + + emit q->pairingDisplayPinCode(address, pin); + return pin; +} + +void QBluetoothLocalDevicePrivate::pairingCompleted(QDBusPendingCallWatcher *watcher) +{ + Q_Q(QBluetoothLocalDevice); + QDBusPendingReply<> reply = *watcher; + + if(reply.isError()) { + qDebug() << Q_FUNC_INFO << "failed to create pairing" << reply.error(); + emit q->pairingFinished(address, QBluetoothLocalDevice::Unpaired); + delete watcher; + return; + } + + QDBusPendingReply<QDBusObjectPath> findReply = adapter->FindDevice(address.toString()); + findReply.waitForFinished(); + if(findReply.isError()) { + qDebug() << Q_FUNC_INFO << "failed to find device" << findReply.error(); + emit q->pairingFinished(address, QBluetoothLocalDevice::Unpaired); + delete watcher; + return; + } + + OrgBluezDeviceInterface device(QLatin1String("org.bluez"), findReply.value().path(), + QDBusConnection::systemBus()); + + if(pairing == QBluetoothLocalDevice::AuthorizedPaired) { + device.SetProperty(QLatin1String("Trusted"), QDBusVariant(QVariant(true))); + emit q->pairingFinished(address, QBluetoothLocalDevice::AuthorizedPaired); + } + else { + device.SetProperty(QLatin1String("Trusted"), QDBusVariant(QVariant(false))); + emit q->pairingFinished(address, QBluetoothLocalDevice::Paired); + } + delete watcher; + +} + +void QBluetoothLocalDevicePrivate::Authorize(const QDBusObjectPath &in0, const QString &in1) +{ + qDebug() << "Got authorize for" << in0.path() << in1; +} + +void QBluetoothLocalDevicePrivate::Cancel() +{ + qDebug() << Q_FUNC_INFO; +} + +void QBluetoothLocalDevicePrivate::Release() +{ + qDebug() << Q_FUNC_INFO; +} + + +void QBluetoothLocalDevicePrivate::ConfirmModeChange(const QString &in0) +{ + qDebug() << Q_FUNC_INFO << in0; +} + +void QBluetoothLocalDevicePrivate::DisplayPasskey(const QDBusObjectPath &in0, uint in1, uchar in2) +{ + qDebug() << Q_FUNC_INFO << in0.path() << in1 << in2; +} + +uint QBluetoothLocalDevicePrivate::RequestPasskey(const QDBusObjectPath &in0) +{ + Q_UNUSED(in0); + qDebug() << Q_FUNC_INFO; + return qrand()&0x1000000; +} + + +void QBluetoothLocalDevicePrivate::PropertyChanged(QString property, QDBusVariant value) +{ + Q_UNUSED(value); + + if (property != QLatin1String("Powered") && + property != QLatin1String("Discoverable")) + return; + + Q_Q(QBluetoothLocalDevice); + QBluetoothLocalDevice::HostMode mode; + + QDBusPendingReply<QVariantMap> reply = adapter->GetProperties(); + reply.waitForFinished(); + if (reply.isError()){ + qWarning() << "Failed to get bluetooth properties for mode change"; + return; + } + + QVariantMap map = reply.value(); + + if(!map.value(QLatin1String("Powered")).toBool()){ + mode = QBluetoothLocalDevice::HostPoweredOff; + } + else { + if (map.value(QLatin1String("Discoverable")).toBool()) + mode = QBluetoothLocalDevice::HostDiscoverable; + else + mode = QBluetoothLocalDevice::HostConnectable; + } + + if(mode != currentMode) + emit q->hostModeStateChanged(mode); + + currentMode = mode; +} + +//#include "qbluetoothlocaldevice.moc" +#include "moc_qbluetoothlocaldevice_p.cpp" diff --git a/src/bluetooth/qbluetoothlocaldevice_p.cpp b/src/bluetooth/qbluetoothlocaldevice_p.cpp new file mode 100644 index 00000000..8173d26e --- /dev/null +++ b/src/bluetooth/qbluetoothlocaldevice_p.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qbluetoothlocaldevice.h" +#include "qbluetoothaddress.h" + + +QBluetoothLocalDevice::QBluetoothLocalDevice(QObject *parent) +: QObject(parent) +{ +} + +QBluetoothLocalDevice::QBluetoothLocalDevice(const QBluetoothAddress &address, QObject *parent) +: QObject(parent) +{ +} + +QString QBluetoothLocalDevice::name() const +{ + return QString(); +} + +QBluetoothAddress QBluetoothLocalDevice::address() const +{ + return QBluetoothAddress(); +} + +void QBluetoothLocalDevice::powerOn() +{ +} + +void QBluetoothLocalDevice::setHostMode(QBluetoothLocalDevice::HostMode mode) +{ + Q_UNUSED(mode); +} + +QBluetoothLocalDevice::HostMode QBluetoothLocalDevice::hostMode() const +{ + return HostPoweredOff; +} + +QList<QBluetoothHostInfo> QBluetoothLocalDevice::allDevices() +{ + QList<QBluetoothHostInfo> localDevices; + return localDevices; +} + +void QBluetoothLocalDevice::requestPairing(const QBluetoothAddress &address, Pairing pairing) +{ + Q_UNUSED(address); + Q_UNUSED(pairing); +} + +QBluetoothLocalDevice::Pairing QBluetoothLocalDevice::pairingStatus(const QBluetoothAddress &address) const +{ + Q_UNUSED(address); + return Unpaired; +} + +void QBluetoothLocalDevice::pairingConfirmation(bool confirmation) +{ + Q_UNUSED(confirmation); +} + diff --git a/src/bluetooth/qbluetoothlocaldevice_p.h b/src/bluetooth/qbluetoothlocaldevice_p.h new file mode 100644 index 00000000..ae461907 --- /dev/null +++ b/src/bluetooth/qbluetoothlocaldevice_p.h @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHLOCALDEVICE_P_H +#define QBLUETOOTHLOCALDEVICE_P_H + +#include "../qtconnectivityglobal.h" + +#include "qbluetoothlocaldevice.h" + +#ifdef QT_SYMBIAN_BLUETOOTH +#include <e32base.h> +#include <btengsettings.h> +#endif + +#ifdef QT_BLUEZ_BLUETOOTH +#include <QObject> +#include <QDBusContext> +#include <QDBusObjectPath> +#include <QDBusMessage> + +class OrgBluezAdapterInterface; +class OrgBluezAgentAdaptor; +class QDBusPendingCallWatcher; +#endif + +QT_BEGIN_HEADER + +class QBluetoothAddress; + +#ifdef QT_BLUEZ_BLUETOOTH +class QBluetoothLocalDevicePrivate : public QObject, + protected QDBusContext +{ + Q_OBJECT + Q_DECLARE_PUBLIC(QBluetoothLocalDevice) +public: + QBluetoothLocalDevicePrivate(); + ~QBluetoothLocalDevicePrivate(); + + OrgBluezAdapterInterface *adapter; + OrgBluezAgentAdaptor *agent; + QString agent_path; + QBluetoothAddress address; + QBluetoothLocalDevice::Pairing pairing; + QBluetoothLocalDevice::HostMode currentMode; + +public Q_SLOTS: // METHODS + void Authorize(const QDBusObjectPath &in0, const QString &in1); + void Cancel(); + void ConfirmModeChange(const QString &in0); + void DisplayPasskey(const QDBusObjectPath &in0, uint in1, uchar in2); + void Release(); + uint RequestPasskey(const QDBusObjectPath &in0); + + void RequestConfirmation(const QDBusObjectPath &in0, uint in1); + QString RequestPinCode(const QDBusObjectPath &in0); + + void pairingCompleted(QDBusPendingCallWatcher*); + + void PropertyChanged(QString,QDBusVariant); + +private: + QDBusMessage msgConfirmation; + QDBusConnection *msgConnection; + + QBluetoothLocalDevice *q_ptr; +}; +#endif + +#ifdef QT_SYMBIAN_BLUETOOTH +class QBluetoothLocalDevicePrivate + : public MBTEngSettingsObserver +{ + Q_DECLARE_PUBLIC(QBluetoothLocalDevice) +public: + QBluetoothLocalDevicePrivate(); + ~QBluetoothLocalDevicePrivate(); + + static QString name(); + static QBluetoothAddress address(); + + void powerOn(); + void powerOff(); + void setHostMode(QBluetoothLocalDevice::HostMode mode); + QBluetoothLocalDevice::HostMode hostMode() const; + + void requestPairing(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing); + QBluetoothLocalDevice::Pairing pairingStatus(const QBluetoothAddress &address) const; + + void pairingConfirmation(bool confirmation); + //slots exposed for the public api. + void _q_pairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing); + void _q_registryError(int error); + void _q_pairingError(int error); + +private: + //From MBTEngSettingsObserver + void PowerStateChanged(TBTPowerStateValue aState); + void VisibilityModeChanged(TBTVisibilityMode aState); + +private: + CBTEngSettings *m_settings; + +protected: + QBluetoothLocalDevice *q_ptr; + +}; +#endif + +QT_END_HEADER + +#endif // QBLUETOOTHLOCALDEVICE_P_H diff --git a/src/bluetooth/qbluetoothlocaldevice_symbian.cpp b/src/bluetooth/qbluetoothlocaldevice_symbian.cpp new file mode 100644 index 00000000..d842d3dc --- /dev/null +++ b/src/bluetooth/qbluetoothlocaldevice_symbian.cpp @@ -0,0 +1,421 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothlocaldevice_p.h" + +#include "qbluetoothlocaldevice.h" +#include <QtCore/QString> +#include "symbian/utils_symbian_p.h" +#include <bttypes.h> +#include <bt_subscribe.h> +#ifdef USING_BTENGCONNMAN +#include "bluetoothsymbianpairingadapter.h" +#endif //USING_BTENGCONNMAN +#ifdef USING_BTENGDEVMAN +#include "bluetoothsymbianregistryadapter.h" +#endif //USING_BTENGDEVMAN + + +QBluetoothLocalDevicePrivate::QBluetoothLocalDevicePrivate() + : m_settings(NULL) +{ + TRAPD(err, m_settings = CBTEngSettings::NewL(this)); + if (err != KErrNone) { + Q_Q(QBluetoothLocalDevice); + emit q->error(QBluetoothLocalDevice::UnknownError); + m_settings = NULL; + } +} + +QBluetoothLocalDevicePrivate::~QBluetoothLocalDevicePrivate() +{ + delete m_settings; +} + +QString QBluetoothLocalDevicePrivate::name() +{ + CBTEngSettings *settings = NULL; + TRAPD(err, settings = CBTEngSettings::NewL()); + if (err != KErrNone) + return QString(); + HBufC *localName = NULL; + TRAPD(error, localName = HBufC::NewL(256)); + if (error != KErrNone) { + delete settings; + return QString(); + } + TPtr localPtr = localName->Des(); + TInt errorCode = settings->GetLocalName(localPtr); + QString name; + if (errorCode == KErrNone) + name = s60DescToQString(localPtr); + + delete localName; + delete settings; + return name; +} + +QBluetoothAddress QBluetoothLocalDevicePrivate::address() +{ + TBuf<20> bluetoothAddress; + TPckgBuf<TBTDevAddr> addressPackage; + + TInt error = RProperty::Get(KUidSystemCategory, KPropertyKeyBluetoothGetLocalDeviceAddress, addressPackage); + + if (error != KErrNone) + return QBluetoothAddress(); + + addressPackage().GetReadable(bluetoothAddress, KNullDesC, _L(":"), KNullDesC); + + return QBluetoothAddress(s60DescToQString(bluetoothAddress)); +} + +void QBluetoothLocalDevicePrivate::powerOn() +{ + if (!m_settings) + return; + TBTPowerStateValue powerState; + TInt error = m_settings->GetPowerState(powerState); + if (error == KErrNone && powerState == EBTPowerOff) + m_settings->SetPowerState(EBTPowerOn); + else if (error != KErrNone) { + Q_Q(QBluetoothLocalDevice); + emit q->error(QBluetoothLocalDevice::UnknownError); + } +} +void QBluetoothLocalDevicePrivate::powerOff() +{ + if (!m_settings) + return; + TBTPowerStateValue powerState; + TInt error = m_settings->GetPowerState(powerState); + if (error == KErrNone && powerState == EBTPowerOn) + m_settings->SetPowerState(EBTPowerOff); + else if (error != KErrNone) { + Q_Q(QBluetoothLocalDevice); + emit q->error(QBluetoothLocalDevice::UnknownError); + } +} +void QBluetoothLocalDevicePrivate::setHostMode(QBluetoothLocalDevice::HostMode mode) +{ + if (!m_settings) + return; + + TInt error = KErrNone; + switch (mode) { + case QBluetoothLocalDevice::HostPoweredOff: + powerOff(); + break; + case QBluetoothLocalDevice::HostConnectable: { + TBTPowerStateValue powerState; + error = m_settings->GetPowerState(powerState); + if (error == KErrNone) { + if (powerState == EBTPowerOff) { + error = m_settings->SetPowerState(EBTPowerOn); + } + TBTVisibilityMode visibilityMode; + error = m_settings->GetVisibilityMode(visibilityMode); + if (visibilityMode != EBTVisibilityModeHidden) { + error = m_settings->SetVisibilityMode(EBTVisibilityModeHidden); + } + } + break; + } + case QBluetoothLocalDevice::HostDiscoverable: { + TBTPowerStateValue powerState; + error = m_settings->GetPowerState(powerState); + if (error == KErrNone) { + if (powerState == EBTPowerOff) { + error = m_settings->SetPowerState(EBTPowerOn); + } + TBTVisibilityMode visibilityMode; + error = m_settings->GetVisibilityMode(visibilityMode); + if (visibilityMode != EBTVisibilityModeGeneral) { + error = m_settings->SetVisibilityMode(EBTVisibilityModeGeneral); + } + } + break; + } + } + if (error != KErrNone) { + Q_Q(QBluetoothLocalDevice); + emit q->error(QBluetoothLocalDevice::UnknownError); + } +} + + +QBluetoothLocalDevice::HostMode QBluetoothLocalDevicePrivate::hostMode() const +{ + if (!m_settings) + return QBluetoothLocalDevice::HostPoweredOff; + + TBTVisibilityMode visibilityMode; + TInt error = m_settings->GetVisibilityMode(visibilityMode); + + if (error != KErrNone) + return QBluetoothLocalDevice::HostPoweredOff; + + //If we are powered off then we don't are neither connectable or discoverable + TBTPowerStateValue powerState; + error = m_settings->GetPowerState(powerState); + if (error == KErrNone && powerState == EBTPowerOff) + return QBluetoothLocalDevice::HostPoweredOff; + + switch (visibilityMode) { + case EBTVisibilityModeHidden: + return QBluetoothLocalDevice::HostConnectable; + case EBTVisibilityModeGeneral: + case EBTVisibilityModeTemporary: + return QBluetoothLocalDevice::HostDiscoverable; + default: + // default value, also includes these new values from Symbian^3 onwards + // case EBTVisibilityModeNoScans: + // case EBTVisibilityModeInquiryScanOnly: + return QBluetoothLocalDevice::HostPoweredOff; + } +} + +void QBluetoothLocalDevicePrivate::PowerStateChanged(TBTPowerStateValue aState) +{ + QBluetoothLocalDevice::HostMode hostMode; + switch (aState) { + case EBTPowerOn: + hostMode = this->hostMode(); + break; + case EBTPowerOff: + default: + hostMode = QBluetoothLocalDevice::HostPoweredOff; + break; + } + Q_Q(QBluetoothLocalDevice); + emit q->hostModeStateChanged(hostMode); +} + +void QBluetoothLocalDevicePrivate::VisibilityModeChanged(TBTVisibilityMode aState) +{ + QBluetoothLocalDevice::HostMode hostMode; + switch (aState) { + case EBTVisibilityModeHidden: + hostMode = QBluetoothLocalDevice::HostConnectable; + break; + case EBTVisibilityModeGeneral: + case EBTVisibilityModeTemporary: + hostMode = QBluetoothLocalDevice::HostDiscoverable; + break; + default: + // default value, also includes these new values from Symbian^3 onwards + // case EBTVisibilityModeNoScans: + // case EBTVisibilityModeInquiryScanOnly: + hostMode = QBluetoothLocalDevice::HostPoweredOff; + break; + } + Q_Q(QBluetoothLocalDevice); + emit q->hostModeStateChanged(hostMode); +} + +void QBluetoothLocalDevicePrivate::requestPairing(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing) +{ +//#ifdef USING_BTENGCONNMAN +#ifdef USING_BTENGDEVMAN + Q_Q(QBluetoothLocalDevice); + + BluetoothSymbianRegistryAdapter *registryAdapter = new BluetoothSymbianRegistryAdapter(address,q); + // do nothing if everything is uptodate. + if (registryAdapter->pairingStatus() == pairing) { + _q_pairingFinished(address, pairing); + return; + } + // pass q pointer so that adapter gets deleted when q object is deleted. Not optimal though. + BluetoothSymbianPairingAdapter *pairingAdapter = new BluetoothSymbianPairingAdapter(address,q); + + // After pairing has completed we emit pairingFinished signal in every case. + // earlier we checked pairing status from Symbian Bluetooth registry at this point but it + // was not updated and the result was that we emitted wrong pairing status. + QObject::connect(pairingAdapter, SIGNAL(pairingFinished(const QBluetoothAddress&,QBluetoothLocalDevice::Pairing)), + q, SLOT(_q_pairingFinished(const QBluetoothAddress&,QBluetoothLocalDevice::Pairing))); + // if pairing status changes then emit pairing finished. + // Currently this is used after removing a paired device from Symbian Bluetooth registry + QObject::connect(registryAdapter, SIGNAL(pairingStatusChanged(const QBluetoothAddress&,QBluetoothLocalDevice::Pairing)), + q, SLOT(_q_pairingFinished(const QBluetoothAddress&,QBluetoothLocalDevice::Pairing))); + // if there are pairing errors, emit them + QObject::connect(registryAdapter, SIGNAL(registryHandlingError(int)), + q, SLOT(_q_registryError(int))); + QObject::connect(pairingAdapter, SIGNAL(pairingError(int)), + q, SLOT(_q_pairingError(int))); + + switch (pairing) { + case QBluetoothLocalDevice::Unpaired: + // this is async method + registryAdapter->removePairing(); + break; + case QBluetoothLocalDevice::Paired: + case QBluetoothLocalDevice::AuthorizedPaired: + // this is async method + // Note: currently Symbian pairing function puts up a user dialog to confirm authorization; + // due to this, we cannot be sure if authorization is done or not, since it depends on user response + pairingAdapter->startPairing(pairing); + break; + default: + ASSERT(0); + break; + } +#endif //USING_BTENGDEVMAN +//#endif USING_BTENGCONNMAN +} + +QBluetoothLocalDevice::Pairing QBluetoothLocalDevicePrivate::pairingStatus(const QBluetoothAddress &address) const +{ +#ifdef USING_BTENGDEVMAN + QScopedPointer<BluetoothSymbianRegistryAdapter> registryAdapter (new BluetoothSymbianRegistryAdapter(address)); + return registryAdapter->pairingStatus(); +#endif //USING_BTENGDEVMAN +} + +void QBluetoothLocalDevicePrivate::pairingConfirmation(bool confirmation) +{ +} + +void QBluetoothLocalDevicePrivate::_q_pairingFinished(const QBluetoothAddress &address,QBluetoothLocalDevice::Pairing pairing) +{ + Q_Q(QBluetoothLocalDevice); + emit q->pairingFinished(address, pairing); +} +void QBluetoothLocalDevicePrivate::_q_registryError(int error) +{ + Q_Q(QBluetoothLocalDevice); + //TODO Add more errorCodes to LocalDevice api and map them to Symbian errorcodes + emit q->error(QBluetoothLocalDevice::UnknownError); +} +void QBluetoothLocalDevicePrivate::_q_pairingError(int error) +{ + Q_Q(QBluetoothLocalDevice); + //TODO Add more errorCodes to LocalDevice api and map them to Symbian errorcodes + emit q->error(QBluetoothLocalDevice::PairingError); +} + +QBluetoothLocalDevice::QBluetoothLocalDevice(QObject *parent) +: QObject(parent), d_ptr(new QBluetoothLocalDevicePrivate()) +{ + d_ptr->q_ptr = this; + if (this->d_ptr->m_settings == NULL) { + delete this->d_ptr; + this->d_ptr = NULL; + } +} + +QBluetoothLocalDevice::QBluetoothLocalDevice(const QBluetoothAddress &address, QObject *parent) +: QObject(parent), d_ptr(new QBluetoothLocalDevicePrivate()) +{ + d_ptr->q_ptr = this; + if (this->d_ptr->m_settings == NULL || address != this->d_ptr->address()) { + delete this->d_ptr; + this->d_ptr = NULL; + } +} + +QString QBluetoothLocalDevice::name() const +{ + if (!d_ptr) + return QString(); + return d_ptr->name(); +} + +QBluetoothAddress QBluetoothLocalDevice::address() const +{ + if (!d_ptr) + return QBluetoothAddress(); + return d_ptr->address(); +} + +void QBluetoothLocalDevice::powerOn() +{ + if (!d_ptr) + return; + d_ptr->powerOn(); +} + +void QBluetoothLocalDevice::setHostMode(QBluetoothLocalDevice::HostMode mode) +{ + if (!d_ptr) + return; + d_ptr->setHostMode(mode); +} + +QBluetoothLocalDevice::HostMode QBluetoothLocalDevice::hostMode() const +{ + if (!d_ptr) + return HostPoweredOff; + return d_ptr->hostMode(); +} + +QList<QBluetoothHostInfo> QBluetoothLocalDevice::allDevices() +{ + QList<QBluetoothHostInfo> localDevices; + QBluetoothHostInfo hostInfo; + hostInfo.setName(QBluetoothLocalDevicePrivate::name()); + hostInfo.setAddress(QBluetoothLocalDevicePrivate::address()); + localDevices.append(hostInfo); + return localDevices; +} + +void QBluetoothLocalDevice::requestPairing(const QBluetoothAddress &address, Pairing pairing) +{ + if (!d_ptr) + return; + + return d_ptr->requestPairing(address, pairing); +} + +QBluetoothLocalDevice::Pairing QBluetoothLocalDevice::pairingStatus(const QBluetoothAddress &address) const +{ + if (!d_ptr) + return QBluetoothLocalDevice::Unpaired; + + return d_ptr->pairingStatus(address); +} + +void QBluetoothLocalDevice::pairingConfirmation(bool confirmation) +{ + if (!d_ptr) + return; + + return d_ptr->pairingConfirmation(confirmation); +} diff --git a/src/bluetooth/qbluetoothservicediscoveryagent.cpp b/src/bluetooth/qbluetoothservicediscoveryagent.cpp new file mode 100644 index 00000000..754e07e0 --- /dev/null +++ b/src/bluetooth/qbluetoothservicediscoveryagent.cpp @@ -0,0 +1,412 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothservicediscoveryagent.h" +#include "qbluetoothservicediscoveryagent_p.h" + +#include "qbluetoothdevicediscoveryagent.h" + +/*! + \class QBluetoothServiceDiscoveryAgent + \brief The QBluetoothServiceDiscoveryAgent class provides an API for querying the services + provided by a Bluetooth device. + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity + \since 5.0 + + To query the services provided by all contactable Bluetooth devices create an instance of + QBluetoothServiceDiscoveryAgent, connect to either the serviceDiscovered() or finished() + signals and call start(). + + \snippet snippets/connectivity/servicediscovery.cpp Service discovery + + By default a minimal service discovery is performed. In this mode the QBluetotohServiceInfo + objects returned are guaranteed to contain only device and service UUID information. Depending + on platform and device capabilities other service information may also be available. For most + use cases this is adequate as QBluetoothSocket::connectToService() will perform additional + discovery if required. If full service information is required pass \l FullDiscovery as the + discoveryMode parameter to start(). +*/ + +/*! + \enum QBluetoothServiceDiscoveryAgent::Error + + This enum describes errors that can occur during service discovery. + + \value NoError No error. + \value DeviceDiscoveryError Error occurred during device discovery. + \value UnknownError An unidentified error occurred. +*/ + +/*! + \enum QBluetoothServiceDiscoveryAgent::DiscoveryMode + + This enum describes the service discovery mode. + + \value MinimalDiscovery Performs a minimal service discovery. The QBluetoothServiceInfo + objects returned may be incomplete and are only guaranteed to + contain device and service UUID information. + \value FullDiscovery Performs a full service discovery. +*/ + +/*! + \fn QBluetoothServiceDiscoveryAgent::serviceDiscovered(const QBluetoothServiceInfo &info) + + This signal is emitted when the Bluetooth service described by \a info is discovered. +*/ + +/*! + \fn QBluetoothServiceDiscoveryAgent::finished() + + This signal is emitted when Bluetooth service discovery completes. +*/ + +/*! + \fn void QBluetoothServiceDiscoveryAgent::error(QBluetoothServiceDiscoveryAgent::Error error) + + This signal is emitted when an error occurs. The \a error parameter describes the error that + occurred. +*/ + +/*! + Constructs a new QBluetoothServiceDiscoveryAgent with \a parent. Services will be discovered on all + contactable devices. +*/ +QBluetoothServiceDiscoveryAgent::QBluetoothServiceDiscoveryAgent(QObject *parent) +: QObject(parent), d_ptr(new QBluetoothServiceDiscoveryAgentPrivate(QBluetoothAddress())) +{ + d_ptr->q_ptr = this; +} + +/*! + Constructs a new QBluetoothServiceDiscoveryAgent for \a remoteAddress and with \a parent. + + If \a remoteAddress is null services will be discovred on all contactable Bluetooth + devices. +*/ +QBluetoothServiceDiscoveryAgent::QBluetoothServiceDiscoveryAgent(const QBluetoothAddress &remoteAddress, QObject *parent) +: QObject(parent), d_ptr(new QBluetoothServiceDiscoveryAgentPrivate(remoteAddress)) +{ + d_ptr->q_ptr = this; + if (!remoteAddress.isNull()) { + d_ptr->singleDevice = true; + } +} + +/*! + + Destructor for QBluetoothServiceDiscoveryAgent + +*/ + +QBluetoothServiceDiscoveryAgent::~QBluetoothServiceDiscoveryAgent() +{ + delete d_ptr; +} + +/*! + Returns the list of all discovered services. +*/ +QList<QBluetoothServiceInfo> QBluetoothServiceDiscoveryAgent::discoveredServices() const +{ + Q_D(const QBluetoothServiceDiscoveryAgent); + + return d->discoveredServices; +} +/*! + Sets the UUID filter to \a uuids. Only services matching the UUIDs in \a uuids will be + returned. + + An empty UUID list is equivalent to a list containing only QBluetoothUuid::PublicBrowseGroup. + + \sa uuidFilter() +*/ +void QBluetoothServiceDiscoveryAgent::setUuidFilter(const QList<QBluetoothUuid> &uuids) +{ + Q_D(QBluetoothServiceDiscoveryAgent); + + d->uuidFilter = uuids; +} + +/*! + This is an overloaded member function, provided for convenience. + + Sets the UUID filter to a list containing the single element \a uuid. + + \sa uuidFilter() +*/ +void QBluetoothServiceDiscoveryAgent::setUuidFilter(const QBluetoothUuid &uuid) +{ + Q_D(QBluetoothServiceDiscoveryAgent); + + d->uuidFilter.clear(); + d->uuidFilter.append(uuid); +} + +/*! + Returns the UUID filter. + + \sa setUuidFilter() +*/ +QList<QBluetoothUuid> QBluetoothServiceDiscoveryAgent::uuidFilter() const +{ + Q_D(const QBluetoothServiceDiscoveryAgent); + + return d->uuidFilter; +} + +/*! + Starts service discovery. \a mode specifies the type of service discovery to perform. + + \sa DiscoveryMode +*/ +void QBluetoothServiceDiscoveryAgent::start(DiscoveryMode mode) +{ + Q_D(QBluetoothServiceDiscoveryAgent); + + if (d->discoveryState() == QBluetoothServiceDiscoveryAgentPrivate::Inactive) { + d->setDiscoveryMode(mode); + if (d->deviceAddress.isNull()) { + d->startDeviceDiscovery(); + } else { + d->discoveredDevices << QBluetoothDeviceInfo(d->deviceAddress, QString(), 0); + d->startServiceDiscovery(); + } + } +} + +/*! + Stops service discovery. +*/ +void QBluetoothServiceDiscoveryAgent::stop() +{ + Q_D(QBluetoothServiceDiscoveryAgent); + + switch (d->discoveryState()) { + case QBluetoothServiceDiscoveryAgentPrivate::DeviceDiscovery: + d->stopDeviceDiscovery(); + break; + case QBluetoothServiceDiscoveryAgentPrivate::ServiceDiscovery: + d->stopServiceDiscovery(); + default: + ; + } + + d->discoveredDevices.clear(); +} + +/*! + Clears the results of a previous service discovery. +*/ +void QBluetoothServiceDiscoveryAgent::clear() +{ + Q_D(QBluetoothServiceDiscoveryAgent); + + d->discoveredDevices.clear(); + d->discoveredServices.clear(); + d->uuidFilter.clear(); +} + +/*! + Returns true if service discovery is currently active, otherwise returns false. +*/ +bool QBluetoothServiceDiscoveryAgent::isActive() const +{ + Q_D(const QBluetoothServiceDiscoveryAgent); + + return d->state != QBluetoothServiceDiscoveryAgentPrivate::Inactive; +} + +/*! + Returns the type of error that last occurred. If service discovery is done + on a signle address it will returns errors when trying to discover services + on that device. If the alternate constructor is used and devices are + discovered by a scan, then errors doing service discovery on individual + devices are not saved and no signals are emitted. In this case errors are + fairly normal since some devices may not respond to discovery or + may no longer be in range. As such errors are surpressed. If no services + are returned, it can be assumed no services could be discovered. + +*/ +QBluetoothServiceDiscoveryAgent::Error QBluetoothServiceDiscoveryAgent::error() const +{ + Q_D(const QBluetoothServiceDiscoveryAgent); + + return d->error; +} + +/*! + Returns a human-readable description of the last error that occurred when + doing service discovery on a single device. +*/ +QString QBluetoothServiceDiscoveryAgent::errorString() const +{ + Q_D(const QBluetoothServiceDiscoveryAgent); + return d->errorString; +} + + +/*! + \fn QBluetoothServiceDiscoveryAgent::canceled() + Signals the cancellation of the service discovery. + */ + + +/*! + Starts device discovery. +*/ +void QBluetoothServiceDiscoveryAgentPrivate::startDeviceDiscovery() +{ + Q_Q(QBluetoothServiceDiscoveryAgent); + + if (!deviceDiscoveryAgent) { + deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent; + QObject::connect(deviceDiscoveryAgent, SIGNAL(finished()), + q, SLOT(_q_deviceDiscoveryFinished())); + QObject::connect(deviceDiscoveryAgent, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)), + q, SLOT(_q_deviceDiscovered(QBluetoothDeviceInfo))); + + } + + setDiscoveryState(DeviceDiscovery); + + deviceDiscoveryAgent->start(); +} + +/*! + Stops device discovery. +*/ +void QBluetoothServiceDiscoveryAgentPrivate::stopDeviceDiscovery() +{ + deviceDiscoveryAgent->stop(); + delete deviceDiscoveryAgent; + deviceDiscoveryAgent = 0; + + setDiscoveryState(Inactive); + + Q_Q(QBluetoothServiceDiscoveryAgent); + emit q->canceled(); +} + +/*! + Called when device discovery finishes. +*/ +void QBluetoothServiceDiscoveryAgentPrivate::_q_deviceDiscoveryFinished() +{ + if (deviceDiscoveryAgent->error() != QBluetoothDeviceDiscoveryAgent::NoError) { + error = QBluetoothServiceDiscoveryAgent::DeviceDiscoveryError; + + setDiscoveryState(Inactive); + Q_Q(QBluetoothServiceDiscoveryAgent); + emit q->finished(); + return; + } + +// discoveredDevices = deviceDiscoveryAgent->discoveredDevices(); + + delete deviceDiscoveryAgent; + deviceDiscoveryAgent = 0; + + startServiceDiscovery(); +} + +void QBluetoothServiceDiscoveryAgentPrivate::_q_deviceDiscovered(const QBluetoothDeviceInfo &info) +{ + if(mode == QBluetoothServiceDiscoveryAgent::FullDiscovery) { + // look for duplicates, and cached entries + for(int i = 0; i < discoveredDevices.count(); i++){ + if(discoveredDevices.at(i).address() == info.address()){ + discoveredDevices.removeAt(i); + } + } + discoveredDevices.prepend(info); + } + else { + for(int i = 0; i < discoveredDevices.count(); i++){ + if(discoveredDevices.at(i).address() == info.address()){ + discoveredDevices.removeAt(i); + } + } + discoveredDevices.prepend(info); + } +} + +/*! + Starts service discovery for the next device. +*/ +void QBluetoothServiceDiscoveryAgentPrivate::startServiceDiscovery() +{ + Q_Q(QBluetoothServiceDiscoveryAgent); + + setDiscoveryState(ServiceDiscovery); + + if (discoveredDevices.isEmpty()) { + setDiscoveryState(Inactive); + emit q->finished(); + return; + } + + setDiscoveryState(ServiceDiscovery); + start(discoveredDevices.at(0).address()); +} + +/*! + Stops service discovery. +*/ +void QBluetoothServiceDiscoveryAgentPrivate::stopServiceDiscovery() +{ + stop(); + + setDiscoveryState(Inactive); +} + +void QBluetoothServiceDiscoveryAgentPrivate::_q_serviceDiscoveryFinished() +{ + if(!discoveredDevices.isEmpty()) { + discoveredDevices.removeFirst(); + } + + startServiceDiscovery(); +} + + +#include "moc_qbluetoothservicediscoveryagent.cpp" diff --git a/src/bluetooth/qbluetoothservicediscoveryagent.h b/src/bluetooth/qbluetoothservicediscoveryagent.h new file mode 100644 index 00000000..042ef190 --- /dev/null +++ b/src/bluetooth/qbluetoothservicediscoveryagent.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHSERVICEDISCOVERYAGENT_H +#define QBLUETOOTHSERVICEDISCOVERYAGENT_H + +#include "../qtconnectivityglobal.h" + +#include <QObject> + +#include <qbluetoothserviceinfo.h> +#include <qbluetoothuuid.h> + +QT_BEGIN_HEADER + +class QBluetoothAddress; +class QBluetoothServiceDiscoveryAgentPrivate; + +class Q_CONNECTIVITY_EXPORT QBluetoothServiceDiscoveryAgent : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QBluetoothServiceDiscoveryAgent) + +public: + enum Error { + NoError, + DeviceDiscoveryError, + UnknownError = 100 + }; + + enum DiscoveryMode { + MinimalDiscovery, + FullDiscovery + }; + + QBluetoothServiceDiscoveryAgent(QObject *parent = 0); + explicit QBluetoothServiceDiscoveryAgent(const QBluetoothAddress &remoteAddress, QObject *parent = 0); + ~QBluetoothServiceDiscoveryAgent(); + + bool isActive() const; + + Error error() const; + QString errorString() const; + + QList<QBluetoothServiceInfo> discoveredServices() const; + + void setUuidFilter(const QList<QBluetoothUuid> &uuids); + void setUuidFilter(const QBluetoothUuid &uuid); + QList<QBluetoothUuid> uuidFilter() const; + +public slots: + void start(DiscoveryMode mode = MinimalDiscovery); + void stop(); + void clear(); + +signals: + void serviceDiscovered(const QBluetoothServiceInfo &info); + void finished(); + void canceled(); + void error(QBluetoothServiceDiscoveryAgent::Error error); + +private: + QBluetoothServiceDiscoveryAgentPrivate *d_ptr; + + Q_PRIVATE_SLOT(d_func(), void _q_deviceDiscovered(const QBluetoothDeviceInfo &info)) + Q_PRIVATE_SLOT(d_func(), void _q_deviceDiscoveryFinished()) + Q_PRIVATE_SLOT(d_func(), void _q_serviceDiscoveryFinished()) +#ifdef QT_BLUEZ_BLUETOOTH + Q_PRIVATE_SLOT(d_func(), void _q_discoveredServices(QDBusPendingCallWatcher*)) + Q_PRIVATE_SLOT(d_func(), void _q_createdDevice(QDBusPendingCallWatcher*)) +#endif +}; + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp new file mode 100644 index 00000000..abcaa23d --- /dev/null +++ b/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp @@ -0,0 +1,323 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothservicediscoveryagent.h" +#include "qbluetoothservicediscoveryagent_p.h" + +#include "bluez/manager_p.h" +#include "bluez/adapter_p.h" +#include "bluez/device_p.h" + +#include <QtDBus/QDBusPendingCallWatcher> + +//#define QTM_SERVICEDISCOVERY_DEBUG + +#ifdef QTM_SERVICEDISCOVERY_DEBUG +#include <QtCore/QDebug> +#endif + +QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(const QBluetoothAddress &address) +: error(QBluetoothServiceDiscoveryAgent::NoError), state(Inactive), deviceAddress(address), + deviceDiscoveryAgent(0), mode(QBluetoothServiceDiscoveryAgent::MinimalDiscovery), + singleDevice(false), manager(0), device(0) +{ + qRegisterMetaType<ServiceMap>("ServiceMap"); + qDBusRegisterMetaType<ServiceMap>(); +} + +QBluetoothServiceDiscoveryAgentPrivate::~QBluetoothServiceDiscoveryAgentPrivate() +{ + delete device; + delete manager; +} + +void QBluetoothServiceDiscoveryAgentPrivate::start(const QBluetoothAddress &address) +{ + Q_Q(QBluetoothServiceDiscoveryAgent); + +#ifdef QTM_SERVICEDISCOVERY_DEBUG + qDebug() << "Full discovery on: " << address.toString(); +#endif + + manager = new OrgBluezManagerInterface(QLatin1String("org.bluez"), QLatin1String("/"), + QDBusConnection::systemBus()); + + QDBusPendingReply<QDBusObjectPath> reply = manager->DefaultAdapter(); + reply.waitForFinished(); + if (reply.isError()) { + if (singleDevice) { + error = QBluetoothServiceDiscoveryAgent::DeviceDiscoveryError; + errorString = QBluetoothServiceDiscoveryAgent::tr("Unable to find default adapter"); + emit q->error(error); + } + _q_serviceDiscoveryFinished(); + return; + } + + adapter = new OrgBluezAdapterInterface(QLatin1String("org.bluez"), reply.value().path(), + QDBusConnection::systemBus()); + + QDBusPendingReply<QDBusObjectPath> deviceObjectPath = adapter->CreateDevice(address.toString()); + + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(deviceObjectPath, q); + watcher->setProperty("_q_BTaddress", QVariant::fromValue(address)); + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + q, SLOT(_q_createdDevice(QDBusPendingCallWatcher*))); + +} + +void QBluetoothServiceDiscoveryAgentPrivate::stop() +{ +#ifdef QTM_SERVICEDISCOVERY_DEBUG + qDebug() << Q_FUNC_INFO << "Stop called"; +#endif + if(device){ + QDBusPendingReply<> reply = device->CancelDiscovery(); + reply.waitForFinished(); + + discoveredDevices.clear(); + setDiscoveryState(Inactive); + Q_Q(QBluetoothServiceDiscoveryAgent); + emit q->canceled(); + +// qDebug() << "Stop done"; + } +} + +void QBluetoothServiceDiscoveryAgentPrivate::_q_createdDevice(QDBusPendingCallWatcher *watcher) +{ + Q_Q(QBluetoothServiceDiscoveryAgent); + + const QBluetoothAddress &address = watcher->property("_q_BTaddress").value<QBluetoothAddress>(); + +#ifdef QTM_SERVICEDISCOVERY_DEBUG + qDebug() << Q_FUNC_INFO << "created" << address.toString(); +#endif + + QDBusPendingReply<QDBusObjectPath> deviceObjectPath = *watcher; + if (deviceObjectPath.isError()) { + if (deviceObjectPath.error().name() != QLatin1String("org.bluez.Error.AlreadyExists")) { + _q_serviceDiscoveryFinished(); +#ifdef QTM_SERVICEDISCOVERY_DEBUG + qDebug() << "Create device failed Error: " << error << deviceObjectPath.error().name(); +#endif + return; + } + + deviceObjectPath = adapter->FindDevice(address.toString()); + deviceObjectPath.waitForFinished(); + if (deviceObjectPath.isError()) { + if (singleDevice) { + error = QBluetoothServiceDiscoveryAgent::DeviceDiscoveryError; + errorString = QBluetoothServiceDiscoveryAgent::tr("Unable to access device"); + emit q->error(error); + } + _q_serviceDiscoveryFinished(); +#ifdef QTM_SERVICEDISCOVERY_DEBUG + qDebug() << "Can't find device after creation Error: " << error << deviceObjectPath.error().name(); +#endif + return; + } + } + + device = new OrgBluezDeviceInterface(QLatin1String("org.bluez"), + deviceObjectPath.value().path(), + QDBusConnection::systemBus()); + + QDBusPendingReply<QVariantMap> deviceReply = device->GetProperties(); + deviceReply.waitForFinished(); + if(deviceReply.isError()) + return; + QVariantMap v = deviceReply.value(); + QStringList device_uuids = v.value(QLatin1String("UUIDs")).toStringList(); + + QString pattern; + foreach (const QBluetoothUuid &uuid, uuidFilter) + pattern += uuid.toString().remove(QLatin1Char('{')).remove(QLatin1Char('}')) + QLatin1Char(' '); + +#ifdef QTM_SERVICEDISCOVERY_DEBUG + qDebug() << Q_FUNC_INFO << "Discover: " << pattern.trimmed(); +#endif + QDBusPendingReply<ServiceMap> discoverReply = device->DiscoverServices(pattern.trimmed()); + watcher = new QDBusPendingCallWatcher(discoverReply, q); + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + q, SLOT(_q_discoveredServices(QDBusPendingCallWatcher*))); + +} + +void QBluetoothServiceDiscoveryAgentPrivate::_q_discoveredServices(QDBusPendingCallWatcher *watcher) +{ +#ifdef QTM_SERVICEDISCOVERY_DEBUG + qDebug() << Q_FUNC_INFO; +#endif + + QDBusPendingReply<ServiceMap> reply = *watcher; + if (reply.isError()) { +#ifdef QTM_SERVICEDISCOVERY_DEBUG + qDebug() << "discoveredServices error: " << error << reply.error().message(); +#endif + watcher->deleteLater(); + if (singleDevice) { + Q_Q(QBluetoothServiceDiscoveryAgent); + error = QBluetoothServiceDiscoveryAgent::UnknownError; + errorString = reply.error().message(); + emit q->error(error); + } + _q_serviceDiscoveryFinished(); + return; + } + + ServiceMap map = reply.value(); + +#ifdef QTM_SERVICEDISCOVERY_DEBUG + qDebug() << "Parsing xml" << discoveredDevices.at(0).address().toString() << discoveredDevices.count() << map.count(); +#endif + + foreach (const QString &record, reply.value()) { + QXmlStreamReader xml(record); + +#ifdef QTM_SERVICEDISCOVERY_DEBUG + // qDebug() << "Service xml" << record; +#endif + + QBluetoothServiceInfo serviceInfo; + serviceInfo.setDevice(discoveredDevices.at(0)); + + while (!xml.atEnd()) { + xml.readNext(); + + if (xml.tokenType() == QXmlStreamReader::StartElement && + xml.name() == QLatin1String("attribute")) { + quint16 attributeId = + xml.attributes().value(QLatin1String("id")).toString().toUShort(0, 0); + + if (xml.readNextStartElement()) { + QVariant value = readAttributeValue(xml); + + serviceInfo.setAttribute(attributeId, value); + } + } + } + + if (!serviceInfo.isValid()) + continue; + + Q_Q(QBluetoothServiceDiscoveryAgent); + + discoveredServices.append(serviceInfo); +#ifdef QTM_SERVICEDISCOVERY_DEBUG + qDebug() << "Discovered services" << discoveredDevices.at(0).address().toString(); +#endif + emit q->serviceDiscovered(serviceInfo); + // could stop discovery, check for state + if(discoveryState() == Inactive){ + qDebug() << "Exit discovery after stop"; + break; + } + } + + watcher->deleteLater(); + + _q_serviceDiscoveryFinished(); +} + +QVariant QBluetoothServiceDiscoveryAgentPrivate::readAttributeValue(QXmlStreamReader &xml) +{ + if (xml.name() == QLatin1String("boolean")) { + const QString value = xml.attributes().value(QLatin1String("value")).toString(); + xml.skipCurrentElement(); + return value == QLatin1String("true"); + } else if (xml.name() == QLatin1String("uint8")) { + quint8 value = xml.attributes().value(QLatin1String("value")).toString().toUShort(0, 0); + xml.skipCurrentElement(); + return value; + } else if (xml.name() == QLatin1String("uint16")) { + quint16 value = xml.attributes().value(QLatin1String("value")).toString().toUShort(0, 0); + xml.skipCurrentElement(); + return value; + } else if (xml.name() == QLatin1String("uint32")) { + quint32 value = xml.attributes().value(QLatin1String("value")).toString().toUInt(0, 0); + xml.skipCurrentElement(); + return value; + } else if (xml.name() == QLatin1String("uint64")) { + quint64 value = xml.attributes().value(QLatin1String("value")).toString().toULongLong(0, 0); + xml.skipCurrentElement(); + return value; + } else if (xml.name() == QLatin1String("uuid")) { + QBluetoothUuid uuid; + const QString value = xml.attributes().value(QLatin1String("value")).toString(); + if (value.startsWith(QLatin1String("0x"))) { + if (value.length() == 6) { + quint16 v = value.toUShort(0, 0); + uuid = QBluetoothUuid(v); + } else if (value.length() == 10) { + quint32 v = value.toUInt(0, 0); + uuid = QBluetoothUuid(v); + } + } else { + uuid = QBluetoothUuid(value); + } + xml.skipCurrentElement(); + return QVariant::fromValue(uuid); + } else if (xml.name() == QLatin1String("text")) { + QString value = xml.attributes().value(QLatin1String("value")).toString(); + if (xml.attributes().value(QLatin1String("encoding")) == QLatin1String("hex")) + value = QString::fromUtf8(QByteArray::fromHex(value.toAscii())); + xml.skipCurrentElement(); + return value; + } else if (xml.name() == QLatin1String("sequence")) { + QBluetoothServiceInfo::Sequence sequence; + + while (xml.readNextStartElement()) { + QVariant value = readAttributeValue(xml); + sequence.append(value); + } + + return QVariant::fromValue<QBluetoothServiceInfo::Sequence>(sequence); + } else { + qWarning("unknown attribute type %s %s", + xml.name().toString().toLocal8Bit().constData(), + xml.attributes().value(QLatin1String("value")).toString().toLocal8Bit().constData()); + Q_ASSERT(false); + xml.skipCurrentElement(); + return QVariant(); + } +} diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_p.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_p.cpp new file mode 100644 index 00000000..fd82a5d3 --- /dev/null +++ b/src/bluetooth/qbluetoothservicediscoveryagent_p.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothservicediscoveryagent.h" +#include "qbluetoothservicediscoveryagent_p.h" + +QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(const QBluetoothAddress &address) +{ + Q_UNUSED(address); +} + +QBluetoothServiceDiscoveryAgentPrivate::~QBluetoothServiceDiscoveryAgentPrivate() +{ +} + +void QBluetoothServiceDiscoveryAgentPrivate::start(const QBluetoothAddress &address) +{ + Q_UNUSED(address); +} + +void QBluetoothServiceDiscoveryAgentPrivate::stop() +{ +} diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_p.h b/src/bluetooth/qbluetoothservicediscoveryagent_p.h new file mode 100644 index 00000000..e60a1ae3 --- /dev/null +++ b/src/bluetooth/qbluetoothservicediscoveryagent_p.h @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHSERVICEDISCOVERYAGENT_P_H +#define QBLUETOOTHSERVICEDISCOVERYAGENT_P_H + +#include "qbluetoothaddress.h" +#include "qbluetoothdeviceinfo.h" +#include "qbluetoothserviceinfo.h" +#include "qbluetoothservicediscoveryagent.h" + +#include <QStack> + +#ifdef QT_SYMBIAN_BLUETOOTH +#include <btsdp.h> +#endif + +#ifdef QT_BLUEZ_BLUETOOTH +class OrgBluezManagerInterface; +class OrgBluezAdapterInterface; +class OrgBluezDeviceInterface; +class QDBusPendingCallWatcher; +class QXmlStreamReader; +#endif + +QT_BEGIN_HEADER + +class QBluetoothDeviceDiscoveryAgent; + +class QBluetoothServiceDiscoveryAgentPrivate +#ifdef QT_SYMBIAN_BLUETOOTH +: public MSdpAgentNotifier, public MSdpAttributeValueVisitor +#endif +{ + Q_DECLARE_PUBLIC(QBluetoothServiceDiscoveryAgent) + +public: + enum DiscoveryState { + Inactive, + DeviceDiscovery, + ServiceDiscovery, + }; + + QBluetoothServiceDiscoveryAgentPrivate(const QBluetoothAddress &address); + ~QBluetoothServiceDiscoveryAgentPrivate(); + + void startDeviceDiscovery(); + void stopDeviceDiscovery(); + void startServiceDiscovery(); + void stopServiceDiscovery(); + + void setDiscoveryState(DiscoveryState s) { state = s; } + DiscoveryState discoveryState() { return state; } + + void setDiscoveryMode(QBluetoothServiceDiscoveryAgent::DiscoveryMode m) { mode = m; } + QBluetoothServiceDiscoveryAgent::DiscoveryMode DiscoveryMode() { return mode; } + + // private slots + void _q_deviceDiscoveryFinished(); + void _q_deviceDiscovered(const QBluetoothDeviceInfo &info); + void _q_serviceDiscoveryFinished(); +#ifdef QT_BLUEZ_BLUETOOTH + void _q_discoveredServices(QDBusPendingCallWatcher *watcher); + void _q_createdDevice(QDBusPendingCallWatcher *watcher); +#endif + +#ifdef QT_SYMBIAN_BLUETOOTH + /* MSdpAgentNotifier virtual functions */ + void NextRecordRequestComplete(TInt aError, TSdpServRecordHandle aHandle, TInt aTotalRecordsCount); + void AttributeRequestResult(TSdpServRecordHandle aHandle, TSdpAttributeID aAttrID, CSdpAttrValue *aAttrValue); + void AttributeRequestComplete(TSdpServRecordHandle, TInt aError); + + /* MSdpAttributeValueVisitor virtual functions */ + void VisitAttributeValueL(CSdpAttrValue &aValue, TSdpElementType aType); + void StartListL(CSdpAttrValueList &); + void EndListL(); +#endif + +private: + void start(const QBluetoothAddress &address); + void stop(); + +#ifdef QT_SYMBIAN_BLUETOOTH + void startL(const QBluetoothAddress &address); + void initL(const QBluetoothAddress &address); +#elif defined(QT_BLUEZ_BLUETOOTH) + QVariant readAttributeValue(QXmlStreamReader &xml); +#endif + +public: + QBluetoothServiceDiscoveryAgent::Error error; + QString errorString; + + QList<QBluetoothServiceInfo> discoveredServices; + QList<QBluetoothDeviceInfo> discoveredDevices; + +private: + DiscoveryState state; + QBluetoothAddress deviceAddress; + QList<QBluetoothUuid> uuidFilter; + + QBluetoothDeviceDiscoveryAgent *deviceDiscoveryAgent; + + QBluetoothServiceDiscoveryAgent::DiscoveryMode mode; + + bool singleDevice; + +#ifdef QT_SYMBIAN_BLUETOOTH + CSdpAgent *m_sdpAgent; + CSdpSearchPattern *m_filter; + CSdpAttrIdMatchList *m_attributes; + QBluetoothServiceInfo m_serviceInfo; + TSdpAttributeID m_currentAttributeId; + + QStack<QVariant> m_stack; +#elif defined(QT_BLUEZ_BLUETOOTH) + OrgBluezManagerInterface *manager; + OrgBluezAdapterInterface *adapter; + OrgBluezDeviceInterface *device; +#endif + +protected: + QBluetoothServiceDiscoveryAgent *q_ptr; +}; + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_symbian.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_symbian.cpp new file mode 100644 index 00000000..da84c0d0 --- /dev/null +++ b/src/bluetooth/qbluetoothservicediscoveryagent_symbian.cpp @@ -0,0 +1,311 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothservicediscoveryagent_p.h" + +#include <QUrl> +#include <QtEndian> + +#include <arpa/inet.h> +#include <netinet/in.h> + +QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(const QBluetoothAddress &address) + : error(QBluetoothServiceDiscoveryAgent::NoError) + , state(Inactive) + , deviceAddress(address) + , deviceDiscoveryAgent(0) + , mode(QBluetoothServiceDiscoveryAgent::MinimalDiscovery) + , singleDevice(false) + , m_sdpAgent(NULL) + , m_filter(NULL) + , m_attributes(NULL) +{ + +} + +QBluetoothServiceDiscoveryAgentPrivate::~QBluetoothServiceDiscoveryAgentPrivate() +{ + qDebug() << "QBluetoothServiceDiscoveryAgent being destroyed"; + delete m_filter; + delete m_attributes; + delete m_sdpAgent; +} + +void QBluetoothServiceDiscoveryAgentPrivate::start(const QBluetoothAddress &address) +{ + Q_Q(QBluetoothServiceDiscoveryAgent); + TRAPD(err, startL(address)); + if (err != KErrNone && singleDevice) { + qDebug() << "Service discovery start failed" << err; + error = QBluetoothServiceDiscoveryAgent::UnknownError; + emit q->error(error); + } + qDebug() << "Service discovery started"; +} + +void QBluetoothServiceDiscoveryAgentPrivate::startL(const QBluetoothAddress &address) +{ + initL(address); + + if (uuidFilter.isEmpty()) { + m_filter->AddL(QBluetoothUuid::PublicBrowseGroup); + } else { + foreach (const QBluetoothUuid &uuid, uuidFilter) { + if (uuid.minimumSize() == 2) { + TUUID sUuid(uuid.toUInt16()); + m_filter->AddL(sUuid); + } else if (uuid.minimumSize() == 4) { + TUUID sUuid(uuid.toUInt32()); + m_filter->AddL(sUuid); + } else if (uuid.minimumSize() == 16) { + TUint32 *dataPointer = (TUint32*)uuid.toUInt128().data; + TUint32 hH = qToBigEndian<quint32>(*(dataPointer++)); + TUint32 hL = qToBigEndian<quint32>(*(dataPointer++)); + TUint32 lH = qToBigEndian<quint32>(*(dataPointer++)); + TUint32 lL = qToBigEndian<quint32>(*(dataPointer)); + TUUID sUuid(hH, hL, lH, lL); + m_filter->AddL(sUuid); + } else { + // filter size can be 0 on error cases, searching all services + m_filter->AddL(QBluetoothUuid::PublicBrowseGroup); + } + } + } + m_sdpAgent->SetRecordFilterL(*m_filter); + m_sdpAgent->NextRecordRequestL(); + qDebug() << "Service discovery started, in startL"; +} + +void QBluetoothServiceDiscoveryAgentPrivate::stop() +{ + qDebug() << "Stop discovery called"; + delete m_sdpAgent; + m_sdpAgent = NULL; + delete m_filter; + m_filter = NULL; + delete m_attributes; + m_attributes = NULL; + Q_Q(QBluetoothServiceDiscoveryAgent); + emit q->canceled(); +} + +void QBluetoothServiceDiscoveryAgentPrivate::initL(const QBluetoothAddress &address) +{ + TBTDevAddr btAddress(address.toUInt64()); + stop(); + + //Trapped in Start + m_sdpAgent = q_check_ptr(CSdpAgent::NewL(*this, btAddress)); + m_filter = q_check_ptr(CSdpSearchPattern::NewL()); + m_attributes = q_check_ptr(CSdpAttrIdMatchList::NewL()); + m_attributes->AddL(KAttrRangeAll); + +} + +void QBluetoothServiceDiscoveryAgentPrivate::NextRecordRequestComplete(TInt aError, TSdpServRecordHandle aHandle, TInt aTotalRecordsCount) +{ + qDebug() << "NextRecordRequestComplete"; + Q_Q(QBluetoothServiceDiscoveryAgent); + if (aError == KErrNone && aTotalRecordsCount > 0 && m_sdpAgent && m_attributes) { + // request attributes + TRAPD(err, m_sdpAgent->AttributeRequestL(aHandle, *m_attributes)); + if (err && singleDevice) { + error = QBluetoothServiceDiscoveryAgent::UnknownError; + emit q->error(error); + } + } else if (aError == KErrEof) { + _q_serviceDiscoveryFinished(); + } else { + _q_serviceDiscoveryFinished(); + } +} + +void QBluetoothServiceDiscoveryAgentPrivate::AttributeRequestResult(TSdpServRecordHandle, TSdpAttributeID aAttrID, CSdpAttrValue *aAttrValue) +{ + qDebug() << "AttributeRequestResult"; + Q_Q(QBluetoothServiceDiscoveryAgent); + m_currentAttributeId = aAttrID; + TRAPD(err, aAttrValue->AcceptVisitorL(*this)); + if (m_stack.size() != 1) { + if(singleDevice) + { + error = QBluetoothServiceDiscoveryAgent::UnknownError; + emit q->error(error); + } + delete aAttrValue; + return; + } + + m_serviceInfo.setAttribute(aAttrID, m_stack.pop()); + + if (err != KErrNone && singleDevice) { + error = QBluetoothServiceDiscoveryAgent::UnknownError; + emit q->error(error); + } + delete aAttrValue; +} + +void QBluetoothServiceDiscoveryAgentPrivate::AttributeRequestComplete(TSdpServRecordHandle, TInt aError) +{ + qDebug() << "AttributeRequestComplete"; + Q_Q(QBluetoothServiceDiscoveryAgent); + + if (aError == KErrNone && m_sdpAgent) { + m_serviceInfo.setDevice(discoveredDevices.at(0)); + discoveredServices.append(m_serviceInfo); + m_serviceInfo = QBluetoothServiceInfo(); + if (discoveredServices.last().isValid()) + { + emit q->serviceDiscovered(discoveredServices.last()); + } + TRAPD(err, m_sdpAgent->NextRecordRequestL()); + if (err != KErrNone && singleDevice) { + error = QBluetoothServiceDiscoveryAgent::UnknownError; + emit q->error(error); + } + } else if (aError != KErrEof && singleDevice) { + error = QBluetoothServiceDiscoveryAgent::UnknownError; + emit q->error(error); + } + + +} + +void QBluetoothServiceDiscoveryAgentPrivate::VisitAttributeValueL(CSdpAttrValue &aValue, TSdpElementType aType) +{ + qDebug() << "VisitAttributeValueL"; + QVariant var; + TUint datasize = aValue.DataSize(); + + switch (aType) { + case ETypeNil: + break; + case ETypeUint: + if (datasize == 8) { + TUint64 value; + aValue.Uint64(value); + var = QVariant::fromValue(value); + } else + var = QVariant::fromValue(aValue.Uint()); + break; + case ETypeInt: + var = QVariant::fromValue(aValue.Int()); + break; + case ETypeUUID: { + TPtrC8 shortForm(aValue.UUID().ShortestForm()); + if (shortForm.Size() == 2) { + QBluetoothUuid uuid(ntohs(*reinterpret_cast<const quint16 *>(shortForm.Ptr()))); + var = QVariant::fromValue(uuid); + } else if (shortForm.Size() == 4) { + QBluetoothUuid uuid(ntohl(*reinterpret_cast<const quint32 *>(shortForm.Ptr()))); + var = QVariant::fromValue(uuid); + } else if (shortForm.Size() == 16) { + QBluetoothUuid uuid(*reinterpret_cast<const quint128 *>(shortForm.Ptr())); + var = QVariant::fromValue(uuid); + } + break; + } + case ETypeString: { + TPtrC8 stringBuffer = aValue.Des(); + var = QVariant::fromValue(QString::fromLocal8Bit(reinterpret_cast<const char *>(stringBuffer.Ptr()), stringBuffer.Size())); + break; + } + case ETypeBoolean: + var = QVariant::fromValue(static_cast<bool>(aValue.Bool())); + break; + case ETypeDES: + m_stack.push(QVariant::fromValue(QBluetoothServiceInfo::Sequence())); + break; + case ETypeDEA: + m_stack.push(QVariant::fromValue(QBluetoothServiceInfo::Alternative())); + break; + case ETypeURL: { + TPtrC8 stringBuffer = aValue.Des(); + var = QVariant::fromValue(QUrl(QString::fromLocal8Bit(reinterpret_cast<const char *>(stringBuffer.Ptr()), stringBuffer.Size()))); + break; + } + case ETypeEncoded: + qWarning() << "Don't know how to handle encoded type."; + break; + default: + qWarning() << "Don't know how to handle type" << aType; + } + + if (aType != ETypeDES && aType != ETypeDEA) { + if (m_stack.size() == 0) { + // single value attribute, just push onto stack + m_stack.push(var); + } else if (m_stack.size() >= 1) { + // sequence or alternate attribute, add non-DES -DEA values to DES or DEA + if (m_stack.top().canConvert<QBluetoothServiceInfo::Sequence>()) { + QBluetoothServiceInfo::Sequence *sequence = static_cast<QBluetoothServiceInfo::Sequence *>(m_stack.top().data()); + sequence->append(var); + } else if (m_stack.top().canConvert<QBluetoothServiceInfo::Alternative>()) { + QBluetoothServiceInfo::Alternative *alternative = static_cast<QBluetoothServiceInfo::Alternative *>(m_stack.top().data()); + alternative->append(var); + } else { + qWarning("Unknown type in the QVariant, should be either a QBluetoothServiceInfo::Sequence or an QBluetoothServiceInfo::Alternative"); + } + } + } +} + +void QBluetoothServiceDiscoveryAgentPrivate::StartListL(CSdpAttrValueList &) +{ + +} + +void QBluetoothServiceDiscoveryAgentPrivate::EndListL() +{ + if (m_stack.size() > 1) { + // finished a sequence or alternative add it to the parent sequence or alternative + QVariant var = m_stack.pop(); + if (m_stack.top().canConvert<QBluetoothServiceInfo::Sequence>()) { + QBluetoothServiceInfo::Sequence *sequence = static_cast<QBluetoothServiceInfo::Sequence *>(m_stack.top().data()); + sequence->append(var); + } else if (m_stack.top().canConvert<QBluetoothServiceInfo::Alternative>()) { + QBluetoothServiceInfo::Alternative *alternative = static_cast<QBluetoothServiceInfo::Alternative *>(m_stack.top().data()); + alternative->append(var); + } else { + qWarning("Unknown type in the QVariant, should be either a QBluetoothServiceInfo::Sequence or an QBluetoothServiceInfo::Alternative"); + } + } +} diff --git a/src/bluetooth/qbluetoothserviceinfo.cpp b/src/bluetooth/qbluetoothserviceinfo.cpp new file mode 100644 index 00000000..efd9d4bf --- /dev/null +++ b/src/bluetooth/qbluetoothserviceinfo.cpp @@ -0,0 +1,604 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothserviceinfo.h" +#include "qbluetoothserviceinfo_p.h" + +#include <QUrl> + +/*! + \class QBluetoothServiceInfo::Sequence + \brief The Sequence class provides a data type for Bluetooth Data + Element Sequence attributes. + \since 5.0 + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity +*/ + +/*! + \fn QBluetoothServiceInfo::Sequence::Sequence() + + Constructs a new empty sequence. +*/ + +/*! + \fn QBluetoothServiceInfo::Sequence::Sequence(const QList<QVariant> &list) + + Constructs a new sequence that is a copy of \a list. +*/ + +/*! + \class QBluetoothServiceInfo::Alternative + \brief The Alternative class provides a data type for Bluetooth Data + Element Alternative attributes. + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity +*/ + +/*! + \fn QBluetoothServiceInfo::Alternative::Alternative() + + Constructs a new empty alternative. +*/ + +/*! + \fn QBluetoothServiceInfo::Alternative::Alternative(const QList<QVariant> &list) + + Constructs a new alternative that is a copy of \a list. +*/ + +/*! + \class QBluetoothServiceInfo + \brief The QBluetoothServiceInfo class provides information about services. + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity + + QBluetoothServiceInfo provides information about a service offered by a Bluetooth device. +*/ + +/*! + \enum QBluetoothServiceInfo::AttributeId + + Bluetooth service attributes. + + \value ServiceClassIds UUIDs of service classes that the service conforms to. + \value ServiceId UUID that uniquely identifies the service. + \value ProtocolDescriptorList List of protocols used by the service. + \value BrowseGroupList List of browse groups the service is in. + \value ServiceAvailability Value indicating the availability of the service. + \value PrimaryLanguageBase Base index for primary language text descriptors. + \value ServiceRecordHandle Specifies a service record from which attributes can be retrieved + \value ServiceName Name of the Bluetooth service in the primary language. + \value ServiceDescription Description of the Bluetooth service in the primary language. + \value ServiceProvider Name of the company / entity that provides the Bluetooth + service primary language. +*/ + +/*! + \enum QBluetoothServiceInfo::Protocol + + This enum describes the socket protocol used by the service. + + \value UnknownProtocol The service uses an unknown socket protocol. + \value L2capProtocol The service uses the L2CAP socket protocol. + \value RfcommProtocol The service uses the RFCOMM socket protocol. +*/ + +/*! + \fn bool QBluetoothServiceInfo::isRegistered() const + + Returns true if the service info is registered with the platforms service discovery protocol + (SDP) implementation; otherwise returns false. +*/ + +/*! + \fn bool QBluetoothServiceInfo::registerService() const + + Registers this service with the platforms service discovery protocol (SDP) implementation, + making it findable by other devices when they perform service discovery. Returns true if the + service is successfully registered, otherwise returns false. Once registered changes to the record + cannot be made. The service must be unregistered and registered. +*/ + +/*! + \fn bool QBluetoothServiceInfo::unregisterService() const + + Unregisters this service with the platforms service discovery protocol (SDP) implementation. + + This service will not longer be findable by other devices via service discovery. + + Returns true if the service is successfully unregistered, otherwise returns false. +*/ + +/*! + \fn void QBluetoothServiceInfo::setAttribute(quint16 attributeId, const QBluetoothUuid &value) + + This is a convenience function. + + Sets the attribute identified by \a attributeId to \a value. +*/ + +/*! + \fn void QBluetoothServiceInfo::setAttribute(quint16 attributeId, const QBluetoothServiceInfo::Sequence &value) + + This is a convenience function. + + Sets the attribute identified by \a attributeId to \a value. +*/ + +/*! + \fn void QBluetoothServiceInfo::setAttribute(quint16 attributeId, const QBluetoothServiceInfo::Alternative &value) + + This is a convenience function. + + Sets the attribute identified by \a attributeId to \a value. +*/ + +/*! + \fn void QBluetoothServiceInfo::setServiceName(const QString &name) + + This is a convenience function. It is equivalent to calling + setAttribute(QBluetoothServiceInfo::ServiceName, name). + + Sets the service name in the primary language to \a name. + + \sa serviceName(), setAttribute() +*/ + +/*! + \fn QString QBluetoothServiceInfo::serviceName() const + + This is a convenience function. It is equivalent to calling + attribute(QBluetoothServiceInfo::ServiceName).toString(). + + Returns the service name in the primary language. + + \sa setServiceName(), attribute() +*/ + +/*! + \fn void QBluetoothServiceInfo::setServiceDescription(const QString &description) + + This is a convenience function. It is equivalent to calling + setAttribute(QBluetoothServiceInfo::ServiceDescription, description). + + Sets the service description in the primary language to \a description. + + \sa serviceDescription(), setAttribute() +*/ + +/*! + \fn QString QBluetoothServiceInfo::serviceDescription() const + + This is a convenience function. It is equivalent to calling + attribute(QBluetoothServiceInfo::ServiceDescription).toString(). + + Returns the service description in the primary language. + + \sa setServiceDescription(), attribute() +*/ + +/*! + \fn void QBluetoothServiceInfo::setServiceProvider(const QString &provider) + + This is a convenience function. It is equivalent to calling + setAttribute(QBluetoothServiceInfo::ServiceProvider, provider). + + Sets the service provider in the primary language to \a provider. + + \sa serviceProvider(), setAttribute() +*/ + +/*! + \fn QString QBluetoothServiceInfo::serviceProvider() const + + This is a convenience function. It is equivalent to calling + attribute(QBluetoothServiceInfo::ServiceProvider).toString(). + + Returns the service provider in the primary language. + + \sa setServiceProvider(), attribute() +*/ + +/*! + \fn void QBluetoothServiceInfo::setServiceAvailability(quint8 availability) + + This is a convenience function. It is equivalent to calling + setAttribute(QBluetoothServiceInfo::ServiceAvailability, availability). + + Sets the availabiltiy of the service to \a availability. + + \sa serviceAvailability(), setAttribute() +*/ + +/*! + \fn quint8 QBluetoothServiceInfo::serviceAvailability() const + + This is a convenience function. It is equivalent to calling + attribute(QBluetoothServiceInfo::ServiceAvailability).toUInt(). + + Returns the availability of the service. + + \sa setServiceAvailability(), attribute() +*/ + +/*! + \fn void QBluetoothServiceInfo::setServiceUuid(const QBluetoothUuid &uuid) + + This is a convenience function. It is equivalent to calling + setAttribute(QBluetoothServiceInfo::ServiceId, uuid). + + Sets the service UUID to \a uuid. + + \sa serviceUuid(), setAttribute() +*/ + +/*! + \fn QBluetoothUuid QBluetoothServiceInfo::serviceUuid() const + + This is a convenience function. It is equivalent to calling + attribute(QBluetoothServiceInfo::ServiceId).value<QBluetoothUuid>(). + + Returns the UUID of the service. + + \sa setServiceUuid(), attribute() +*/ + +/*! + \fn QList<QBluetoothUuid> QBluetoothServiceInfo::serviceClassUuids() const + + This is a convenience function. It is equivalent to calling + attribute(QBluetoothServiceInfo::ServiceClassIds).value<QList<QBluetoothUuid> >(). + + Returns a list of UUIDs describing the service classes that this service conforms to. + + \sa attribute() +*/ + + +/*! + Construct a new invalid QBluetoothServiceInfo; +*/ +QBluetoothServiceInfo::QBluetoothServiceInfo() +: d_ptr(new QBluetoothServiceInfoPrivate) +{ + d_ptr->q_ptr = this; +} + +/*! + Construct a new QBluetoothServiceInfo that is a copy of \a other. +*/ +QBluetoothServiceInfo::QBluetoothServiceInfo(const QBluetoothServiceInfo &other) +: d_ptr(new QBluetoothServiceInfoPrivate) +{ + d_ptr->q_ptr = this; + *this = other; +} + +/*! + Destroys the QBluetoothServiceInfo object. +*/ +QBluetoothServiceInfo::~QBluetoothServiceInfo() +{ + delete d_ptr; +} + +/*! + Returns true if the Bluetooth service info object is valid; otherwise returns false. + + An invalid Bluetooth service info has no attributes. +*/ +bool QBluetoothServiceInfo::isValid() const +{ + Q_D(const QBluetoothServiceInfo); + + return !d->attributes.isEmpty(); +} + +/*! + Returns true if the Bluetooth service info object is considered complete; otherwise returns false. + + A complete service info contains a ProtocolDescriptorList attribute. +*/ +bool QBluetoothServiceInfo::isComplete() const +{ + Q_D(const QBluetoothServiceInfo); + + return d->attributes.keys().contains(ProtocolDescriptorList); +} + +/*! + Returns the address of the Bluetooth device that provides this service. +*/ +QBluetoothDeviceInfo QBluetoothServiceInfo::device() const +{ + Q_D(const QBluetoothServiceInfo); + + return d->deviceInfo; +} + +/*! + Sets the Bluetooth device that provides this service to \a device. +*/ +void QBluetoothServiceInfo::setDevice(const QBluetoothDeviceInfo &device) +{ + Q_D(QBluetoothServiceInfo); + + d->deviceInfo = device; +} + +/*! + Sets the attribute identified by \a attributeId to \a value. + + IF the service info is registered with the platforms SDP database the database entry is also + updated. + + \sa isRegistered(), registerService() +*/ +void QBluetoothServiceInfo::setAttribute(quint16 attributeId, const QVariant &value) +{ + Q_D(QBluetoothServiceInfo); + + if (value.type() == QVariant::List) + qDebug() << "tried attribute with type QVariantList" << value; + + d->attributes[attributeId] = value; + + if (isRegistered()) + d->setRegisteredAttribute(attributeId, value); +} + +/*! + Returns the value of the attribute \a attributeId. +*/ +QVariant QBluetoothServiceInfo::attribute(quint16 attributeId) const +{ + Q_D(const QBluetoothServiceInfo); + + return d->attributes[attributeId]; +} + +/*! + Returns a list of all attribute ids that this service info has. +*/ +QList<quint16> QBluetoothServiceInfo::attributes() const +{ + Q_D(const QBluetoothServiceInfo); + + return d->attributes.keys(); +} + +/*! + Returns true if the service info contains the attribute \a attributeId; otherwise returns + false. +*/ +bool QBluetoothServiceInfo::contains(quint16 attributeId) const +{ + Q_D(const QBluetoothServiceInfo); + + return d->attributes.contains(attributeId); +} + +/*! + Removes the attribute \a attributeId from this service info. +*/ +void QBluetoothServiceInfo::removeAttribute(quint16 attributeId) +{ + Q_D(QBluetoothServiceInfo); + + d->attributes.remove(attributeId); + + if (isRegistered()) + d->removeRegisteredAttribute(attributeId); +} + +/*! + Returns the protocol that this service uses. +*/ +QBluetoothServiceInfo::Protocol QBluetoothServiceInfo::socketProtocol() const +{ + QBluetoothServiceInfo::Sequence parameters = protocolDescriptor(QBluetoothUuid::Rfcomm); + if (!parameters.isEmpty()) + return RfcommProtocol; + + parameters = protocolDescriptor(QBluetoothUuid::L2cap); + if (!parameters.isEmpty()) + return L2capProtocol; + + return UnknownProtocol; +} + +/*! + This is a convenience function. Returns the protocol/service multiplexer for services which + support the L2CAP protocol. Otherwise returns -1. + + This function is equivalent to extracting the information from the + QBluetoothServiceInfo::Sequence returned from + QBluetoothServiceInfo::attribute(QBluetoothServiceInfo::ProtocolDescriptorList). +*/ +int QBluetoothServiceInfo::protocolServiceMultiplexer() const +{ + QBluetoothServiceInfo::Sequence parameters = protocolDescriptor(QBluetoothUuid::L2cap); + + if (parameters.isEmpty()) + return -1; + else if (parameters.count() == 1) + return 0; + else + return parameters.at(1).toUInt(); +} + +/*! + This is a convenience function. Returns the server channel for services which support the + RFCOMM protocol. Otherwise returns -1. + + This function is equivalent to extracting the information from the + QBluetoothServiceInfo::Sequence returned from + QBluetoothServiceInfo::attribute(QBluetootherServiceInfo::ProtocolDescriptorList). +*/ +int QBluetoothServiceInfo::serverChannel() const +{ + QBluetoothServiceInfo::Sequence parameters = protocolDescriptor(QBluetoothUuid::Rfcomm); + + if (parameters.isEmpty()) + return -1; + else if (parameters.count() == 1) + return 0; + else + return parameters.at(1).toUInt(); +} + +/*! + Returns the protocol parameters as a QBluetoothServiceInfo::Sequence for protocol \a protocol. + + An empty QBluetoothServiceInfo::Sequence is returned if \a protocol is not supported. +*/ +QBluetoothServiceInfo::Sequence QBluetoothServiceInfo::protocolDescriptor(QBluetoothUuid::ProtocolUuid protocol) const +{ + if (!contains(QBluetoothServiceInfo::ProtocolDescriptorList)) + return QBluetoothServiceInfo::Sequence(); + + foreach (const QVariant &v, attribute(QBluetoothServiceInfo::ProtocolDescriptorList).value<QBluetoothServiceInfo::Sequence>()) { + QBluetoothServiceInfo::Sequence parameters = v.value<QBluetoothServiceInfo::Sequence>(); + if(parameters.empty()) + continue; + if (parameters.at(0).userType() == qMetaTypeId<QBluetoothUuid>()) { + if (parameters.at(0).value<QBluetoothUuid>() == protocol) + return parameters; + } + } + + return QBluetoothServiceInfo::Sequence(); +} + +/*! + Makes a copy of the \a other and assigns it to this QBluetoothServiceInfo object. +*/ +QBluetoothServiceInfo &QBluetoothServiceInfo::operator=(const QBluetoothServiceInfo &other) +{ + Q_D(QBluetoothServiceInfo); + + d->attributes = other.d_func()->attributes; + d->deviceInfo = other.d_func()->deviceInfo; + + return *this; +} + +static void dumpAttributeVariant(const QVariant &var, const QString indent) +{ + switch (var.type()) { + case QMetaType::Void: + qDebug("%sEmpty", indent.toLocal8Bit().constData()); + break; + case QMetaType::UChar: + qDebug("%suchar %u", indent.toLocal8Bit().constData(), var.toUInt()); + break; + case QMetaType::UShort: + qDebug("%sushort %u", indent.toLocal8Bit().constData(), var.toUInt()); + case QMetaType::UInt: + qDebug("%suint %u", indent.toLocal8Bit().constData(), var.toUInt()); + break; + case QMetaType::Char: + qDebug("%schar %d", indent.toLocal8Bit().constData(), var.toInt()); + break; + case QMetaType::Short: + qDebug("%sshort %d", indent.toLocal8Bit().constData(), var.toInt()); + break; + case QMetaType::Int: + qDebug("%sint %d", indent.toLocal8Bit().constData(), var.toInt()); + break; + case QMetaType::QString: + qDebug("%sstring %s", indent.toLocal8Bit().constData(), var.toString().toLocal8Bit().constData()); + break; + case QMetaType::Bool: + qDebug("%sbool %d", indent.toLocal8Bit().constData(), var.toBool()); + break; + case QMetaType::QUrl: + qDebug("%surl %s", indent.toLocal8Bit().constData(), var.toUrl().toString().toLocal8Bit().constData()); + break; + case QVariant::UserType: + if (var.userType() == qMetaTypeId<QBluetoothUuid>()) { + QBluetoothUuid uuid = var.value<QBluetoothUuid>(); + switch (uuid.minimumSize()) { + case 0: + qDebug("%suuid NULL", indent.toLocal8Bit().constData()); + break; + case 2: + qDebug("%suuid %04x", indent.toLocal8Bit().constData(), uuid.toUInt16()); + break; + case 4: + qDebug("%suuid %08x", indent.toLocal8Bit().constData(), uuid.toUInt32()); + break; + case 16: + qDebug("%suuid %s", indent.toLocal8Bit().constData(), QByteArray(reinterpret_cast<const char *>(uuid.toUInt128().data), 16).toHex().constData()); + break; + default: + qDebug("%suuid ???", indent.toLocal8Bit().constData()); + ; + } + } else if (var.userType() == qMetaTypeId<QBluetoothServiceInfo::Sequence>()) { + qDebug("%sSequence", indent.toLocal8Bit().constData()); + const QBluetoothServiceInfo::Sequence *sequence = static_cast<const QBluetoothServiceInfo::Sequence *>(var.data()); + foreach (const QVariant &v, *sequence) + dumpAttributeVariant(v, indent + QLatin1Char('\t')); + } else if (var.userType() == qMetaTypeId<QBluetoothServiceInfo::Alternative>()) { + qDebug("%sAlternative", indent.toLocal8Bit().constData()); + const QBluetoothServiceInfo::Alternative *alternative = static_cast<const QBluetoothServiceInfo::Alternative *>(var.data()); + foreach (const QVariant &v, *alternative) + dumpAttributeVariant(v, indent + QLatin1Char('\t')); + } + break; + default: + qDebug("%sunknown variant type %d", indent.toLocal8Bit().constData(), var.userType()); + } +} + + +QDebug operator<<(QDebug dbg, const QBluetoothServiceInfo &info) +{ + foreach (quint16 id, info.attributes()) { + dumpAttributeVariant(info.attribute(id), QString::fromLatin1("(%1)\t").arg(id)); + } + return dbg; +} diff --git a/src/bluetooth/qbluetoothserviceinfo.h b/src/bluetooth/qbluetoothserviceinfo.h new file mode 100644 index 00000000..f05ed565 --- /dev/null +++ b/src/bluetooth/qbluetoothserviceinfo.h @@ -0,0 +1,229 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHSERVICEINFO_H +#define QBLUETOOTHSERVICEINFO_H + +#include "../qtconnectivityglobal.h" + +#include <qbluetoothuuid.h> + +#include <QtCore/QMetaType> +#include <QtCore/QList> +#include <QtCore/QVariant> + +#include <QtCore/QDebug> + +QT_BEGIN_HEADER + +class QBluetoothServiceInfoPrivate; +class QBluetoothDeviceInfo; + +class Q_CONNECTIVITY_EXPORT QBluetoothServiceInfo +{ +public: + enum AttributeId { + ServiceRecordHandle = 0x0000, + ServiceClassIds = 0x0001, + ServiceId = 0x0003, + ProtocolDescriptorList = 0x0004, + BrowseGroupList = 0x0005, + ServiceAvailability = 0x0008, + PrimaryLanguageBase = 0x0100, + ServiceName = PrimaryLanguageBase + 0x0000, + ServiceDescription = PrimaryLanguageBase + 0x0001, + ServiceProvider = PrimaryLanguageBase + 0x0002, + }; + + enum Protocol { + UnknownProtocol, + L2capProtocol, + RfcommProtocol + }; + + class Sequence : public QList<QVariant> + { + public: + Sequence() { } + Sequence(const QList<QVariant> &list) : QList<QVariant>(list) { } + }; + + class Alternative : public QList<QVariant> + { + public: + Alternative() { } + Alternative(const QList<QVariant> &list) : QList<QVariant>(list) { } + }; + + QBluetoothServiceInfo(); + QBluetoothServiceInfo(const QBluetoothServiceInfo &other); + ~QBluetoothServiceInfo(); + + bool isValid() const; + bool isComplete() const; + + void setDevice(const QBluetoothDeviceInfo &info); + QBluetoothDeviceInfo device() const; + + void setAttribute(quint16 attributeId, const QVariant &value); + void setAttribute(quint16 attributeId, const QBluetoothUuid &value); + void setAttribute(quint16 attributeId, const QBluetoothServiceInfo::Sequence &value); + void setAttribute(quint16 attributeId, const QBluetoothServiceInfo::Alternative &value); + QVariant attribute(quint16 attributeId) const; + QList<quint16> attributes() const; + bool contains(quint16 attributeId) const; + void removeAttribute(quint16 attributeId); + + inline void setServiceName(const QString &name); + inline QString serviceName() const; + inline void setServiceDescription(const QString &description); + inline QString serviceDescription() const; + inline void setServiceProvider(const QString &provider); + inline QString serviceProvider() const; + + QBluetoothServiceInfo::Protocol socketProtocol() const; + int protocolServiceMultiplexer() const; + int serverChannel() const; + + QBluetoothServiceInfo::Sequence protocolDescriptor(QBluetoothUuid::ProtocolUuid protocol) const; + + inline void setServiceAvailability(quint8 availability); + inline quint8 serviceAvailability() const; + + inline void setServiceUuid(const QBluetoothUuid &uuid); + inline QBluetoothUuid serviceUuid() const; + + inline QList<QBluetoothUuid> serviceClassUuids() const; + + QBluetoothServiceInfo &operator=(const QBluetoothServiceInfo &other); + + bool isRegistered() const; + bool registerService() const; + bool unregisterService() const; + +protected: + friend Q_CONNECTIVITY_EXPORT QDebug operator<<(QDebug, const QBluetoothServiceInfo &); + +protected: + QBluetoothServiceInfoPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QBluetoothServiceInfo) +}; + +Q_DECLARE_METATYPE(QBluetoothServiceInfo) +Q_DECLARE_METATYPE(QBluetoothServiceInfo::Sequence) +Q_DECLARE_METATYPE(QBluetoothServiceInfo::Alternative) +Q_DECLARE_METATYPE(QList<QBluetoothUuid>) + +inline void QBluetoothServiceInfo::setAttribute(quint16 attributeId, const QBluetoothUuid &value) +{ + setAttribute(attributeId, QVariant::fromValue(value)); +} + +inline void QBluetoothServiceInfo::setAttribute(quint16 attributeId, const QBluetoothServiceInfo::Sequence &value) +{ + setAttribute(attributeId, QVariant::fromValue(value)); +} + +inline void QBluetoothServiceInfo::setAttribute(quint16 attributeId, const QBluetoothServiceInfo::Alternative &value) +{ + setAttribute(attributeId, QVariant::fromValue(value)); +} + +inline void QBluetoothServiceInfo::setServiceName(const QString &name) +{ + setAttribute(ServiceName, QVariant::fromValue(name)); +} + +inline QString QBluetoothServiceInfo::serviceName() const +{ + return attribute(ServiceName).toString(); +} + +inline void QBluetoothServiceInfo::setServiceDescription(const QString &description) +{ + setAttribute(ServiceDescription, QVariant::fromValue(description)); +} + +inline QString QBluetoothServiceInfo::serviceDescription() const +{ + return attribute(ServiceDescription).toString(); +} + +inline void QBluetoothServiceInfo::setServiceProvider(const QString &provider) +{ + setAttribute(ServiceProvider, QVariant::fromValue(provider)); +} + +inline QString QBluetoothServiceInfo::serviceProvider() const +{ + return attribute(ServiceProvider).toString(); +} + +inline void QBluetoothServiceInfo::setServiceAvailability(quint8 availability) +{ + setAttribute(ServiceAvailability, QVariant::fromValue(availability)); +} + +inline quint8 QBluetoothServiceInfo::serviceAvailability() const +{ + return attribute(ServiceAvailability).toUInt(); +} + +inline void QBluetoothServiceInfo::setServiceUuid(const QBluetoothUuid &uuid) +{ + setAttribute(ServiceId, uuid); +} + +inline QBluetoothUuid QBluetoothServiceInfo::serviceUuid() const +{ + return attribute(ServiceId).value<QBluetoothUuid>(); +} + +inline QList<QBluetoothUuid> QBluetoothServiceInfo::serviceClassUuids() const +{ + return attribute(ServiceClassIds).value<QList<QBluetoothUuid> >(); +} + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/qbluetoothserviceinfo_bluez.cpp b/src/bluetooth/qbluetoothserviceinfo_bluez.cpp new file mode 100644 index 00000000..1bf2b96e --- /dev/null +++ b/src/bluetooth/qbluetoothserviceinfo_bluez.cpp @@ -0,0 +1,296 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothserviceinfo.h" +#include "qbluetoothserviceinfo_p.h" + +#include "bluez/manager_p.h" +#include "bluez/service_p.h" + +#include <QtCore/QXmlStreamWriter> + +static void writeAttribute(QXmlStreamWriter *stream, const QVariant &attribute) +{ + const QString unsignedFormat(QLatin1String("0x%1")); + + switch (attribute.type()) { + case QMetaType::Void: + stream->writeEmptyElement(QLatin1String("nil")); + break; + case QMetaType::UChar: + stream->writeEmptyElement(QLatin1String("uint8")); + stream->writeAttribute(QLatin1String("value"), + unsignedFormat.arg(attribute.value<quint8>(), 2, 16, + QLatin1Char('0'))); + //stream->writeAttribute(QLatin1String("name"), foo); + break; + case QMetaType::UShort: + stream->writeEmptyElement(QLatin1String("uint16")); + stream->writeAttribute(QLatin1String("value"), + unsignedFormat.arg(attribute.value<quint16>(), 4, 16, + QLatin1Char('0'))); + //stream->writeAttribute(QLatin1String("name"), foo); + break; + case QMetaType::UInt: + stream->writeEmptyElement(QLatin1String("uint32")); + stream->writeAttribute(QLatin1String("value"), + unsignedFormat.arg(attribute.value<quint32>(), 8, 16, + QLatin1Char('0'))); + //stream->writeAttribute(QLatin1String("name"), foo); + break; + case QMetaType::Char: + stream->writeEmptyElement(QLatin1String("int8")); + stream->writeAttribute(QLatin1String("value"), + QString::number(attribute.value<uchar>(), 16)); + //stream->writeAttribute(QLatin1String("name"), foo); + break; + case QMetaType::Short: + stream->writeEmptyElement(QLatin1String("int16")); + stream->writeAttribute(QLatin1String("value"), + QString::number(attribute.value<qint16>(), 16)); + //stream->writeAttribute(QLatin1String("name"), foo); + break; + case QMetaType::Int: + stream->writeEmptyElement(QLatin1String("int32")); + stream->writeAttribute(QLatin1String("value"), + QString::number(attribute.value<qint32>(), 16)); + //stream->writeAttribute(QLatin1String("name"), foo); + break; + case QMetaType::QString: + stream->writeEmptyElement(QLatin1String("text")); + if (/* require hex encoding */ false) { + stream->writeAttribute(QLatin1String("value"), QString::fromLatin1( + attribute.value<QString>().toUtf8().toHex().constData())); + stream->writeAttribute(QLatin1String("encoding"), QLatin1String("hex")); + } else { + stream->writeAttribute(QLatin1String("value"), attribute.value<QString>()); + stream->writeAttribute(QLatin1String("encoding"), QLatin1String("normal")); + } + //stream->writeAttribute(QLatin1String("name"), foo); + break; + case QMetaType::Bool: + stream->writeEmptyElement(QLatin1String("boolean")); + if (attribute.value<bool>()) + stream->writeAttribute(QLatin1String("value"), QLatin1String("true")); + else + stream->writeAttribute(QLatin1String("value"), QLatin1String("false")); + //stream->writeAttribute(QLatin1String("name"), foo); + break; + case QMetaType::QUrl: + stream->writeEmptyElement(QLatin1String("url")); + stream->writeAttribute(QLatin1String("value"), attribute.value<QUrl>().toString()); + //stream->writeAttribute(QLatin1String("name"), foo); + break; + case QVariant::UserType: + if (attribute.userType() == qMetaTypeId<QBluetoothUuid>()) { + stream->writeEmptyElement(QLatin1String("uuid")); + + QBluetoothUuid uuid = attribute.value<QBluetoothUuid>(); + switch (uuid.minimumSize()) { + case 0: + stream->writeAttribute(QLatin1String("value"), + unsignedFormat.arg(quint16(0), 4, 16, QLatin1Char('0'))); + break; + case 2: + stream->writeAttribute(QLatin1String("value"), + unsignedFormat.arg(uuid.toUInt16(), 4, 16, + QLatin1Char('0'))); + break; + case 4: + stream->writeAttribute(QLatin1String("value"), + unsignedFormat.arg(uuid.toUInt32(), 8, 16, + QLatin1Char('0'))); + break; + case 16: + stream->writeAttribute(QLatin1String("value"), uuid.toString().mid(1, 36)); + break; + default: + stream->writeAttribute(QLatin1String("value"), uuid.toString().mid(1, 36)); + } + } else if (attribute.userType() == qMetaTypeId<QBluetoothServiceInfo::Sequence>()) { + stream->writeStartElement(QLatin1String("sequence")); + const QBluetoothServiceInfo::Sequence *sequence = + static_cast<const QBluetoothServiceInfo::Sequence *>(attribute.data()); + foreach (const QVariant &v, *sequence) + writeAttribute(stream, v); + stream->writeEndElement(); + } else if (attribute.userType() == qMetaTypeId<QBluetoothServiceInfo::Alternative>()) { + const QBluetoothServiceInfo::Alternative *alternative = + static_cast<const QBluetoothServiceInfo::Alternative *>(attribute.data()); + foreach (const QVariant &v, *alternative) + writeAttribute(stream, v); + stream->writeEndElement(); + } + break; + default: + qDebug() << "Unknown variant type", attribute.userType(); + } +} + +bool QBluetoothServiceInfo::isRegistered() const +{ + Q_D(const QBluetoothServiceInfo); + + return d->registered; +} + +bool QBluetoothServiceInfo::registerService() const +{ + Q_D(const QBluetoothServiceInfo); + + return d->registerService(); +} + +bool QBluetoothServiceInfo::unregisterService() const +{ + Q_D(const QBluetoothServiceInfo); + + if (!d->registered) + return false; + + if (!d->ensureSdpConnection()) + return false; + + QDBusPendingReply<> reply = d->service->RemoveRecord(d->serviceRecord); + reply.waitForFinished(); + if (reply.isError()) + return false; + + d->serviceRecord = 0; + + d->registered = false; + return true; +} + +QBluetoothServiceInfoPrivate::QBluetoothServiceInfoPrivate() +: service(0), serviceRecord(0), registered(false) +{ +} + +QBluetoothServiceInfoPrivate::~QBluetoothServiceInfoPrivate() +{ +} + +void QBluetoothServiceInfoPrivate::setRegisteredAttribute(quint16 attributeId, const QVariant &value) const +{ + Q_UNUSED(attributeId); + Q_UNUSED(value); + + registerService(); +} + +void QBluetoothServiceInfoPrivate::removeRegisteredAttribute(quint16 attributeId) const +{ + Q_UNUSED(attributeId); + + registerService(); +} + +bool QBluetoothServiceInfoPrivate::ensureSdpConnection() const +{ + if (service) + return true; + + OrgBluezManagerInterface manager(QLatin1String("org.bluez"), QLatin1String("/"), + QDBusConnection::systemBus()); + + QDBusPendingReply<QDBusObjectPath> reply = manager.FindAdapter(QLatin1String("any")); + reply.waitForFinished(); + if (reply.isError()) + return false; + + service = new OrgBluezServiceInterface(QLatin1String("org.bluez"), reply.value().path(), + QDBusConnection::systemBus()); + + return true; +} + +bool QBluetoothServiceInfoPrivate::registerService() const +{ + if (!ensureSdpConnection()) + return false; + + QString xmlServiceRecord; + + QXmlStreamWriter stream(&xmlServiceRecord); + stream.setAutoFormatting(true); + + stream.writeStartDocument(QLatin1String("1.0")); + + stream.writeStartElement(QLatin1String("record")); + + const QString unsignedFormat(QLatin1String("0x%1")); + + QMap<quint16, QVariant>::ConstIterator i = attributes.constBegin(); + while (i != attributes.constEnd()) { + QString t = unsignedFormat.arg(i.key(), 4, QLatin1Char('0')); + stream.writeStartElement(QLatin1String("attribute")); + stream.writeAttribute(QLatin1String("id"), + unsignedFormat.arg(i.key(), 4, 16, QLatin1Char('0'))); + writeAttribute(&stream, i.value()); + stream.writeEndElement(); + + ++i; + } + + stream.writeEndElement(); + + stream.writeEndDocument(); + +// qDebug() << xmlServiceRecord; + + if (!registered) { + QDBusPendingReply<uint> reply = service->AddRecord(xmlServiceRecord); + reply.waitForFinished(); + if (reply.isError()) + return false; + + serviceRecord = reply.value(); + } else { + QDBusPendingReply<> reply = service->UpdateRecord(serviceRecord, xmlServiceRecord); + reply.waitForFinished(); + if (reply.isError()) + return false; + } + + registered = true; + return true; +} diff --git a/src/bluetooth/qbluetoothserviceinfo_p.cpp b/src/bluetooth/qbluetoothserviceinfo_p.cpp new file mode 100644 index 00000000..6eb40cab --- /dev/null +++ b/src/bluetooth/qbluetoothserviceinfo_p.cpp @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothserviceinfo.h" +#include "qbluetoothserviceinfo_p.h" + + +bool QBluetoothServiceInfo::isRegistered() const +{ + return false; +} + +bool QBluetoothServiceInfo::registerService() const +{ + return false; +} + +bool QBluetoothServiceInfo::unregisterService() const +{ + return false; +} + +QBluetoothServiceInfoPrivate::QBluetoothServiceInfoPrivate() +{ +} + +QBluetoothServiceInfoPrivate::~QBluetoothServiceInfoPrivate() +{ +} + +void QBluetoothServiceInfoPrivate::setRegisteredAttribute(quint16 attributeId, const QVariant &value) const +{ + Q_UNUSED(attributeId); + Q_UNUSED(value); +} + +void QBluetoothServiceInfoPrivate::removeRegisteredAttribute(quint16 attributeId) const +{ + Q_UNUSED(attributeId); +} + +#ifdef QT_BLUEZ_BLUETOOTH +bool QBluetoothServiceInfoPrivate::registerService() const +{ + return false; +} +#endif diff --git a/src/bluetooth/qbluetoothserviceinfo_p.h b/src/bluetooth/qbluetoothserviceinfo_p.h new file mode 100644 index 00000000..13cbce1c --- /dev/null +++ b/src/bluetooth/qbluetoothserviceinfo_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHSERVICEINFO_P_H +#define QBLUETOOTHSERVICEINFO_P_H + +#include "qbluetoothuuid.h" +#include "qbluetoothdeviceinfo.h" + +#include <QMap> +#include <QVariant> + +#ifdef QT_SYMBIAN_BLUETOOTH +#include <btsdp.h> +#endif + +class OrgBluezServiceInterface; + +QT_BEGIN_HEADER + +class QBluetoothServiceInfo; + +class QBluetoothServiceInfoPrivate +{ + Q_DECLARE_PUBLIC(QBluetoothServiceInfo) +public: + QBluetoothServiceInfoPrivate(); + ~QBluetoothServiceInfoPrivate(); + + void setRegisteredAttribute(quint16 attributeId, const QVariant &value) const; + void removeRegisteredAttribute(quint16 attributeId) const; + + bool ensureSdpConnection() const; + +#ifdef QT_BLUEZ_BLUETOOTH + bool registerService() const; +#endif + + QBluetoothDeviceInfo deviceInfo; + QMap<quint16, QVariant> attributes; + +#ifdef QT_SYMBIAN_BLUETOOTH +private: + void setRegisteredAttributeL(quint16 attributeId, const QVariant &value) const; + +public: + mutable RSdp sdpSession; + mutable RSdpDatabase sdpDatabase; + mutable TSdpServRecordHandle serviceRecord; +#endif + +#ifdef QT_BLUEZ_BLUETOOTH + mutable OrgBluezServiceInterface *service; + mutable quint32 serviceRecord; + mutable bool registered; +#endif + +private: + QBluetoothServiceInfo *q_ptr; +}; + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/qbluetoothserviceinfo_symbian.cpp b/src/bluetooth/qbluetoothserviceinfo_symbian.cpp new file mode 100644 index 00000000..939a74b5 --- /dev/null +++ b/src/bluetooth/qbluetoothserviceinfo_symbian.cpp @@ -0,0 +1,302 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothserviceinfo.h" +#include "qbluetoothserviceinfo_p.h" + +#include <QUrl> +#include <QtEndian> + +#include <QDebug> + + +QBluetoothServiceInfoPrivate::QBluetoothServiceInfoPrivate() +:serviceRecord(0) +{ +} + +QBluetoothServiceInfoPrivate::~QBluetoothServiceInfoPrivate() +{ + // Closing the database session will cause all + // registered services removed from the SDP database. + if (sdpDatabase.SubSessionHandle() != 0) + sdpDatabase.Close(); + + if (sdpSession.Handle() != 0) + sdpSession.Close(); +} + +static void convertL(MSdpElementBuilder *list, const QList<QVariant> &vList) +{ + list->StartListL(); + + foreach (const QVariant &v, vList) { + switch (v.type()) { + case QMetaType::Void: + list->BuildNilL(); + break; + case QMetaType::UChar: + list->BuildUintL(TSdpIntBuf<unsigned char>(v.toUInt())); + break; + case QMetaType::UShort: + list->BuildUintL(TSdpIntBuf<unsigned short>(v.toUInt())); + break; + case QMetaType::UInt: + list->BuildUintL(TSdpIntBuf<uint>(v.toUInt())); + break; + case QMetaType::Char: + list->BuildIntL(TSdpIntBuf<char>(v.toInt())); + break; + case QMetaType::Short: + list->BuildIntL(TSdpIntBuf<short>(v.toInt())); + break; + case QMetaType::Int: + list->BuildIntL(TSdpIntBuf<int>(v.toInt())); + break; + case QMetaType::QString: + list->BuildStringL(TPtrC8(reinterpret_cast<const quint8*>(v.toString().toLocal8Bit().constData()))); + break; + case QMetaType::Bool: + list->BuildBooleanL(v.toBool()); + break; + case QMetaType::QUrl: + list->BuildURLL(TPtrC8(reinterpret_cast<const quint8*>(v.toUrl().toString().toLocal8Bit().constData()))); + break; + case QVariant::UserType: + if (v.userType() == qMetaTypeId<QBluetoothUuid>()) { + QBluetoothUuid uuid = v.value<QBluetoothUuid>(); + switch (uuid.minimumSize()) { + case 2: + list->BuildUUIDL(uuid.toUInt16()); + break; + case 4: + list->BuildUUIDL(uuid.toUInt32()); + break; + case 16: { + TUint32 *dataPointer = (TUint32*)uuid.toUInt128().data; + TUint32 hH = qToBigEndian<quint32>(*(dataPointer++)); + TUint32 hL = qToBigEndian<quint32>(*(dataPointer++)); + TUint32 lH = qToBigEndian<quint32>(*(dataPointer++)); + TUint32 lL = qToBigEndian<quint32>(*(dataPointer)); + TUUID sUuid(hH, hL, lH, lL); + list->BuildUUIDL(sUuid); + break; + } + } + } else if (v.userType() == qMetaTypeId<QBluetoothServiceInfo::Sequence>()) { + convertL(list->BuildDESL(), v.value<QBluetoothServiceInfo::Sequence>()); + } else if (v.userType() == qMetaTypeId<QBluetoothServiceInfo::Alternative>()) { + convertL(list->BuildDEAL(), v.value<QBluetoothServiceInfo::Alternative>()); + } + break; + default: + qDebug() << __FUNCTION__ << "Don't know how to handle variant type" << v.type(); + } + } + + list->EndListL(); +} + +void QBluetoothServiceInfoPrivate::setRegisteredAttribute(quint16 attributeId, const QVariant &value) const +{ + TRAPD(err, setRegisteredAttributeL(attributeId, value)); + if (err != KErrNone) { + qWarning("Could not set attributes SDP session (error %d).", err); + } +} + +void QBluetoothServiceInfoPrivate::setRegisteredAttributeL(quint16 attributeId, const QVariant &value) const +{ + CSdpAttrValue *sdpValue = 0; + + switch (value.type()) { + case QMetaType::Void: + sdpValue = CSdpAttrValueNil::NewNilL(); + break; + case QMetaType::UChar: + sdpValue = CSdpAttrValueUint::NewUintL(TSdpIntBuf<unsigned char>(value.toUInt())); + break; + case QMetaType::UShort: + sdpValue = CSdpAttrValueUint::NewUintL(TSdpIntBuf<unsigned short>(value.toUInt())); + break; + case QMetaType::UInt: + sdpValue = CSdpAttrValueUint::NewUintL(TSdpIntBuf<uint>(value.toUInt())); + break; + case QMetaType::Char: + sdpValue = CSdpAttrValueInt::NewIntL(TSdpIntBuf<char>(value.toInt())); + break; + case QMetaType::Short: + sdpValue = CSdpAttrValueInt::NewIntL(TSdpIntBuf<short>(value.toInt())); + break; + case QMetaType::Int: + sdpValue = CSdpAttrValueInt::NewIntL(TSdpIntBuf<int>(value.toInt())); + break; + case QMetaType::QString: + sdpValue = CSdpAttrValueString::NewStringL(TPtrC8(reinterpret_cast<const quint8*>(value.toString().toLocal8Bit().constData()))); + break; + case QMetaType::Bool: + sdpValue = CSdpAttrValueBoolean::NewBoolL(value.toBool()); + break; + case QMetaType::QUrl: + sdpValue = CSdpAttrValueURL::NewURLL(TPtrC8(reinterpret_cast<const quint8*>(value.toUrl().toString().toLocal8Bit().constData()))); + break; + case QVariant::UserType: + if (value.userType() == qMetaTypeId<QBluetoothUuid>()) { + QBluetoothUuid uuid = value.value<QBluetoothUuid>(); + switch (uuid.minimumSize()) { + case 2: + sdpValue = CSdpAttrValueUUID::NewUUIDL(uuid.toUInt16()); + break; + case 4: + sdpValue = CSdpAttrValueUUID::NewUUIDL(uuid.toUInt32()); + break; + case 16: { + TUint32 *dataPointer = (TUint32*)uuid.toUInt128().data; + TUint32 hH = qToBigEndian<quint32>(*(dataPointer++)); + TUint32 hL = qToBigEndian<quint32>(*(dataPointer++)); + TUint32 lH = qToBigEndian<quint32>(*(dataPointer++)); + TUint32 lL = qToBigEndian<quint32>(*(dataPointer)); + TUUID sUuid(hH, hL, lH, lL); + sdpValue = CSdpAttrValueUUID::NewUUIDL(sUuid); + break; + } + } + } else if (value.userType() == qMetaTypeId<QBluetoothServiceInfo::Sequence>()) { + CSdpAttrValueDES *sequence = CSdpAttrValueDES::NewDESL(0); + CleanupStack::PushL(sequence); + convertL(sequence, value.value<QBluetoothServiceInfo::Sequence>()); + sdpValue = sequence; + CleanupStack::Pop(sequence); + } else if (value.userType() == qMetaTypeId<QBluetoothServiceInfo::Alternative>()) { + CSdpAttrValueDEA *alternative = CSdpAttrValueDEA::NewDEAL(0); + CleanupStack::PushL(alternative); + convertL(alternative, value.value<QBluetoothServiceInfo::Alternative>()); + sdpValue = alternative; + CleanupStack::Pop(alternative); + } + break; + default: + qDebug() << __FUNCTION__ << "Don't know how to handle variant type" << value.type(); + } + + if (sdpValue) { + CleanupStack::PushL(sdpValue); + sdpDatabase.UpdateAttributeL(serviceRecord, attributeId, *sdpValue); + CleanupStack::PopAndDestroy(sdpValue); + } +} + +void QBluetoothServiceInfoPrivate::removeRegisteredAttribute(quint16 attributeId) const +{ + TRAPD(err, sdpDatabase.DeleteAttributeL(serviceRecord, attributeId)); + if (err != KErrNone) { + qWarning("Could not remove registered attribute (error %d).", err); + } +} + +bool QBluetoothServiceInfoPrivate::ensureSdpConnection() const +{ + if (sdpSession.Handle() == 0) { + int error = sdpSession.Connect(); + if (error != KErrNone) { + qWarning("Could not open connection to SDP session (error %d).", error); + return false; + } + } + + if (sdpDatabase.SubSessionHandle() == 0) { + int error = sdpDatabase.Open(sdpSession); + if (error != KErrNone) { + qWarning("Could not open connection to SDP database (error %d).", error); + return false; + } + } + + return true; +} + +bool QBluetoothServiceInfo::isRegistered() const +{ + Q_D(const QBluetoothServiceInfo); + + return d->serviceRecord != 0; +} + +bool QBluetoothServiceInfo::registerService() const +{ + Q_D(const QBluetoothServiceInfo); + + if (d->serviceRecord != 0) + return false; + + if (!d->ensureSdpConnection()) + return false; + + TRAPD(err, d->sdpDatabase.CreateServiceRecordL(0, d->serviceRecord)); + if (err != KErrNone) + return false; + + foreach (quint16 id, d->attributes.keys()) { + // Changing service record handle causes serious problems + // on Symbian devices. Hence passing the value update. + if (id != ServiceRecordHandle) + d->setRegisteredAttribute(id, d->attributes[id]); + } + + return true; +} + +bool QBluetoothServiceInfo::unregisterService() const +{ + Q_D(const QBluetoothServiceInfo); + if(d->serviceRecord == 0) + return true; + + if (!d->ensureSdpConnection()) + return false; + + TRAPD(err, d->sdpDatabase.DeleteRecordL(d->serviceRecord)); + if (err != KErrNone) + return false; + + d->serviceRecord = 0; + return true; +} diff --git a/src/bluetooth/qbluetoothsocket.cpp b/src/bluetooth/qbluetoothsocket.cpp new file mode 100644 index 00000000..d265cc22 --- /dev/null +++ b/src/bluetooth/qbluetoothsocket.cpp @@ -0,0 +1,660 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothsocket.h" +#include "qbluetoothsocket_p.h" + +#include "qbluetoothdeviceinfo.h" +#include "qbluetoothserviceinfo.h" +#include "qbluetoothservicediscoveryagent.h" + + +#include <QDebug> +#include <QSocketNotifier> + +/*! + \class QBluetoothSocket + \brief The QBluetoothSocket class provides a Bluetooth socket. + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity + \since 5.0 + + QBluetoothSocket supports two socket types, \l {QBluetoothSocket::L2capSocket}{L2CAP} and + \l {QBluetoothSocket::RfcommSocket}{RFCOMM}. + + \l {QBluetoothSocket::L2capSocket}{L2CAP} is a low level datagram-oriented Bluetooth socket. + + \l {QBluetoothSocket::RfcommSocket}{RFCOMM} is a reliable, stream-oriented socket. RFCOMM + sockets emulate an RS-232 serial port. + + To create a connection to a Bluetooth service create a socket of the appropriate type and call + connectToService() passing the Bluetooth address and port number. QBluetoothSocket will emit + the connected() signal when the connection is established. + + +*/ + +/*! + \enum QBluetoothSocket::SocketType + + This enum describes the Bluetooth socket type. + + \value UnknownSocketType Unknown socket type. + \value L2capSocket L2CAP socket. + \value RfcommSocket RFCOMM socket. +*/ + +/*! + \enum QBluetoothSocket::SocketState + + This enum describes the state of the Bluetooth socket. + + \value UnconnectedState Socket is not connected. + \value ServiceLookupState Socket is querying connection parameters. + \value ConnectingState Socket is attempting to connect to a device. + \value ConnectedState Socket is connected to a device. + \value BoundState 242.nmp.nokia.com +_IceTransSocketUNIXConnect: Cannot connect to non-local host saisd Socket is bound to a local address and port. + \value ClosingState Socket is connected and will be closed once all pending data is + written to the socket. + \value ListeningState Socket is listening for incoming connections. +*/ + +/*! + \enum QBluetoothSocket::SocketError + + This enum describes Bluetooth socket error types. + + \value UnknownSocketError An unknown error has occurred. + \value NoSocketError No error. Used for testing. + \value ConnectionRefusedError Connection refused or device not available. + \value RemoteHostClosedError The remote host closed the socket + \value HostNotFoundError Could not find the remote host + \value ServiceNotFoundError Could not find the service UUID on remote host + \value NetworkError Attempt to read or write from socket returned an error +*/ + +/*! + \fn void QBluetoothSocket::connected() + + This signal is emitted when a connection is established. + + \sa QBluetoothSocket::ConnectedState, stateChanged() +*/ + +/*! + \fn void QBluetoothSocket::disconnected() + + This signal is emitted when the socket is disconnected. + + \sa QBluetoothSocket::UnconnectedState, stateChanged() +*/ + +/*! + \fn void QBluetoothSocket::error(QBluetoothSocket::SocketError error) + + This signal is emitted when an \a error occurs. + + \sa error() +*/ + +/*! + \fn QBluetoothSocket::stateChanged(QBluetoothSocket::SocketState state) + + This signal is emitted when the socket state changes to \a state. + + \sa connected(), disconnected(), state(), QBluetoothSocket::SocketState +*/ + +/*! + \fn void QBluetoothSocket::abort() + + Aborts the current connection and resets the socket. Unlike disconnectFromService(), this + function immediately closes the socket, discarding any pending data in the write buffer. + + \sa disconnectFromService(), close() +*/ + +/*! + \fn void QBluetoothSocket::close() + + Disconnects the socket's connection with the device. +*/ + +/*! + \fn void QBluetoothSocket::disconnectFromService() + + Attempts to close the socket. If there is pending data waiting to be written QBluetoothSocket + will enter ClosingState and wait until all data has been written. Eventually, it will enter + UnconnectedState and emit the disconnected() signal. + + \sa connectToService() +*/ + +/*! + \fn QString QBluetoothSocket::localName() const + + Returns the name of the local device. +*/ + +/*! + \fn QBluetoothAddress QBluetoothSocket::localAddress() const + + Returns the address of the local device. +*/ + +/*! + \fn quint16 QBluetoothSocket::localPort() const + + Returns the port number of the local socket if available; otherwise returns 0. +*/ + +/*! + \fn QString QBluetoothSocket::peerName() const + + Returns the name of the peer device. +*/ + +/*! + \fn QBluetoothAddress QBluetoothSocket::peerAddress() const + + Returns the address of the peer device. +*/ + +/*! + \fn quint16 QBluetoothSocket::peerPort() const + + Return the port number of the peer socket if available; otherwise returns 0. +*/ + +/*! + \fn qint64 QBluetoothSocket::readData(char *data, qint64 maxSize) + + \reimp +*/ + +/*! + \fn qint64 QBluetoothSocket::writeData(const char *data, qint64 maxSize) + + \reimp +*/ + +/*! + Constructs a Bluetooth socket of \a socketType type, with \a parent. +*/ +QBluetoothSocket::QBluetoothSocket(QBluetoothSocket::SocketType socketType, QObject *parent) +: QIODevice(parent), d_ptr(new QBluetoothSocketPrivate) +{ + d_ptr->q_ptr = this; + + Q_D(QBluetoothSocket); + d->ensureNativeSocket(socketType); + + setOpenMode(QIODevice::ReadWrite); +} + +/*! + Constructs a Bluetooth socket with \a parent. +*/ +QBluetoothSocket::QBluetoothSocket(QObject *parent) + : QIODevice(parent), d_ptr(new QBluetoothSocketPrivate) +{ + d_ptr->q_ptr = this; + setOpenMode(QIODevice::ReadWrite); +} + +/*! + Destroys the Bluetooth socket. +*/ +QBluetoothSocket::~QBluetoothSocket() +{ + delete d_ptr; + d_ptr = 0; +} + +/*! + \reimp +*/ +bool QBluetoothSocket::isSequential() const +{ + return true; +} + +/*! + Returns the number of incoming bytes that are waiting to be read. + + \sa bytesToWrite(), read() +*/ +qint64 QBluetoothSocket::bytesAvailable() const +{ + Q_D(const QBluetoothSocket); + return QIODevice::bytesAvailable() + d->bytesAvailable(); +} + +/*! + Returns the number of bytes that are waiting to be written. The bytes are written when control + goes back to the event loop. +*/ +qint64 QBluetoothSocket::bytesToWrite() const +{ + Q_D(const QBluetoothSocket); + return d->txBuffer.size(); +} + +/*! + Attempts to connect to the service described by \a service. + + The socket is opened in the given \a openMode. + + The socket first enters ConnectingState and attempts to connect to the device providing + \a service. If a connection is established, QBluetoothSocket enters ConnectedState and + emits connected(). + + At any point, the socket can emit error() to siganl that an error occurred. + + \sa state(), disconnectFromService() +*/ +void QBluetoothSocket::connectToService(const QBluetoothServiceInfo &service, OpenMode openMode) +{ + Q_D(QBluetoothSocket); + setOpenMode(openMode); + + if (service.protocolServiceMultiplexer() > 0) { + if (!d->ensureNativeSocket(L2capSocket)) { + emit error(UnknownSocketError); + return; + } + d->connectToService(service.device().address(), service.protocolServiceMultiplexer(), openMode); + } else if (service.serverChannel() > 0) { + if (!d->ensureNativeSocket(RfcommSocket)) { + emit error(UnknownSocketError); + return; + } + d->connectToService(service.device().address(), service.serverChannel(), openMode); + } else { + // try doing service discovery to see if we can find the socket + if(service.serviceUuid().isNull()){ + qWarning() << "No port, no PSM, and no UUID provided, unable to connect"; + return; + } + qDebug() << "Need a port/psm, doing discovery"; + doDeviceDiscovery(service, openMode); + } +} + +/*! + Attempts to make a connection to the service identified by \a uuid on the device with address + \a address. + + The socket is opened in the given \a openMode. + + The socket first enters the ServiceLookupState and queries the connection parameters for + \a uuid. If the service parameters are successfully retrieved the socket enters + ConnectingState, and attempts to connect to \a address. If a connection is established, + QBluetoothSocket enters Connected State and emits connected(). + + At any point, the socket can emit error() to signal that an error occurred. + + \sa state(), disconnectFromService() +*/ +void QBluetoothSocket::connectToService(const QBluetoothAddress &address, const QBluetoothUuid &uuid, OpenMode openMode) +{ + QBluetoothServiceInfo service; + QBluetoothDeviceInfo device(address, QString(), QBluetoothDeviceInfo::MiscellaneousDevice); + service.setDevice(device); + service.setServiceUuid(uuid); + doDeviceDiscovery(service, openMode); +} + +/*! + Attempts to make a connection with \a address on the given \a port. + + The socket is opened in the given \a openMode. + + The socket first enters ConnectingState, and attempts to connect to \a address. If a + connection is established, QBluetoothSocket enters ConnectedState and emits connected(). + + At any point, the socket can emit error() to signal that an error occurred. + + \sa state(), disconnectFromService() +*/ +void QBluetoothSocket::connectToService(const QBluetoothAddress &address, quint16 port, OpenMode openMode) +{ + Q_D(QBluetoothSocket); + setOpenMode(openMode); + + d->connectToService(address, port, openMode); +} + +/*! + Returns the socket type. +*/ +QBluetoothSocket::SocketType QBluetoothSocket::socketType() const +{ + Q_D(const QBluetoothSocket); + return d->socketType; +} + +/*! + Returns the current state of the socket. +*/ +QBluetoothSocket::SocketState QBluetoothSocket::state() const +{ + Q_D(const QBluetoothSocket); + return d->state; +} + +/*! + Returns the last error. +*/ +QBluetoothSocket::SocketError QBluetoothSocket::error() const +{ + Q_D(const QBluetoothSocket); + return d->socketError; +} + +/*! + Returns a user displayable text string for the error. + */ +QString QBluetoothSocket::errorString() const +{ + Q_D(const QBluetoothSocket); + return d->errorString; +} + +/*! + Sets the socket state to \a state. +*/ +void QBluetoothSocket::setSocketState(QBluetoothSocket::SocketState state) +{ + Q_D(QBluetoothSocket); + SocketState old = d->state; + d->state = state; + if(old != d->state) + emit stateChanged(state); + if(state == ListeningState){ + // TODO: look at this, is this really correct? + // if we're a listening socket we can't handle connects? + if (d->readNotifier) { + d->readNotifier->setEnabled(false); + } + } +} + +/*! + Returns true if you can read at least one line from the device + */ + +bool QBluetoothSocket::canReadLine() const +{ + Q_D(const QBluetoothSocket); + return d->buffer.canReadLine() || QIODevice::canReadLine(); +} + +/*! + Sets the type of error that last occurred to \a error_. +*/ +void QBluetoothSocket::setSocketError(QBluetoothSocket::SocketError error_) +{ + Q_D(QBluetoothSocket); + d->socketError = error_; + emit error(error_); +} + +/*! + Start device discovery for \a service and open the socket with \a openMode. If the socket + is created with a service uuid device address we must use service discovery to find the + port number to connect to. +*/ + +void QBluetoothSocket::doDeviceDiscovery(const QBluetoothServiceInfo &service, OpenMode openMode) +{ + Q_D(QBluetoothSocket); + + qDebug() << "Starting discovery"; + + if(d->discoveryAgent) { + delete d->discoveryAgent; + } + + d->discoveryAgent = new QBluetoothServiceDiscoveryAgent(service.device().address(),this); + + qDebug() << "Got agent"; + + connect(d->discoveryAgent, SIGNAL(serviceDiscovered(QBluetoothServiceInfo)), this, SLOT(serviceDiscovered(QBluetoothServiceInfo))); + connect(d->discoveryAgent, SIGNAL(finished()), this, SLOT(discoveryFinished())); + + d->openMode = openMode; + + if(!service.serviceUuid().isNull()) + d->discoveryAgent->setUuidFilter(service.serviceUuid()); + + if(!service.serviceClassUuids().isEmpty()) + d->discoveryAgent->setUuidFilter(service.serviceClassUuids()); + + // we have to ID the service somehow + Q_ASSERT(!d->discoveryAgent->uuidFilter().isEmpty()); + + qDebug() << "UUID filter" << d->discoveryAgent->uuidFilter(); + + d->discoveryAgent->start(QBluetoothServiceDiscoveryAgent::FullDiscovery); +} + +void QBluetoothSocket::serviceDiscovered(const QBluetoothServiceInfo &service) +{ + Q_D(QBluetoothSocket); + qDebug() << "FOUND SERVICE!" << service; + if(service.protocolServiceMultiplexer() != 0 || service.serverChannel() != 0) { + connectToService(service, d->openMode); + d->discoveryAgent->deleteLater(); + d->discoveryAgent = 0; + } +} + +void QBluetoothSocket::discoveryFinished() +{ + qDebug() << "Socket discovery finished"; + Q_D(QBluetoothSocket); + if(d->discoveryAgent){ + qDebug() << "Didn't find any"; + emit error(QBluetoothSocket::ServiceNotFoundError); + d->discoveryAgent->deleteLater(); + d->discoveryAgent = 0; + } +} + +void QBluetoothSocket::abort() +{ + Q_D(QBluetoothSocket); + d->abort(); + setSocketState(QBluetoothSocket::UnconnectedState); +} + +void QBluetoothSocket::disconnectFromService() +{ + // TODO: is this all we need to do? + Q_D(QBluetoothSocket); + d->close(); +} + +QString QBluetoothSocket::localName() const +{ + Q_D(const QBluetoothSocket); + return d->localName(); +} + +QBluetoothAddress QBluetoothSocket::localAddress() const +{ + Q_D(const QBluetoothSocket); + return d->localAddress(); +} + +quint16 QBluetoothSocket::localPort() const +{ + Q_D(const QBluetoothSocket); + return d->localPort(); +} + +QString QBluetoothSocket::peerName() const +{ + Q_D(const QBluetoothSocket); + return d->peerName(); +} + +QBluetoothAddress QBluetoothSocket::peerAddress() const +{ + Q_D(const QBluetoothSocket); + return d->peerAddress(); +} + +quint16 QBluetoothSocket::peerPort() const +{ + Q_D(const QBluetoothSocket); + return d->peerPort(); +} + +qint64 QBluetoothSocket::writeData(const char *data, qint64 maxSize) +{ + Q_D(QBluetoothSocket); + return d->writeData(data, maxSize); +} + +qint64 QBluetoothSocket::readData(char *data, qint64 maxSize) +{ + Q_D(QBluetoothSocket); + return d->readData(data, maxSize); +} + +void QBluetoothSocket::close() +{ + Q_D(QBluetoothSocket); + setSocketState(ClosingState); + + d->close(); + + setSocketState(UnconnectedState); +} + +/*! + Set the socket to use \a socketDescriptor with a type of \a socketType + which is in state \a socketState and mode \a openMode. + + Returns true on success +*/ + + +bool QBluetoothSocket::setSocketDescriptor(int socketDescriptor, SocketType socketType, + SocketState socketState, OpenMode openMode) +{ + Q_D(QBluetoothSocket); + return d->setSocketDescriptor(socketDescriptor, socketType, socketState, openMode); +} + +/*! + Returns the platform specific socket descriptor, if available +*/ + +int QBluetoothSocket::socketDescriptor() const +{ + Q_D(const QBluetoothSocket); + return d->socket; +} + + + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug debug, QBluetoothSocket::SocketError error) +{ + switch (error) { + case QBluetoothSocket::UnknownSocketError: + debug << "QBluetoothSocket::UnknownSocketError"; + break; + case QBluetoothSocket::ConnectionRefusedError: + debug << "QBluetoothSocket::ConnectionRefusedError"; + break; + case QBluetoothSocket::RemoteHostClosedError: + debug << "QBluetoothSocket::RemoteHostClosedError"; + break; + case QBluetoothSocket::HostNotFoundError: + debug << "QBluetoothSocket::HostNotFoundError"; + break; + case QBluetoothSocket::ServiceNotFoundError: + debug << "QBluetoothSocket::ServiceNotFoundError"; + break; + case QBluetoothSocket::NetworkError: + debug << "QBluetoothSocket::NetworkError"; + break; + default: + debug << "QBluetoothSocket::SocketError(" << (int)error << ")"; + } + return debug; +} + +QDebug operator<<(QDebug debug, QBluetoothSocket::SocketState state) +{ + switch (state) { + case QBluetoothSocket::UnconnectedState: + debug << "QBluetoothSocket::UnconnectedState"; + break; + case QBluetoothSocket::ConnectingState: + debug << "QBluetoothSocket::ConnectingState"; + break; + case QBluetoothSocket::ConnectedState: + debug << "QBluetoothSocket::ConnectedState"; + break; + case QBluetoothSocket::BoundState: + debug << "QBluetoothSocket::BoundState"; + break; + case QBluetoothSocket::ClosingState: + debug << "QBluetoothSocket::ClosingState"; + break; + case QBluetoothSocket::ListeningState: + debug << "QBluetoothSocket::ListeningState"; + break; + default: + debug << "QBluetoothSocket::SocketState(" << (int)state << ")"; + } + return debug; +} +#endif + +#include "moc_qbluetoothsocket.cpp" diff --git a/src/bluetooth/qbluetoothsocket.h b/src/bluetooth/qbluetoothsocket.h new file mode 100644 index 00000000..8afea8ad --- /dev/null +++ b/src/bluetooth/qbluetoothsocket.h @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHSOCKET_H +#define QBLUETOOTHSOCKET_H + +#include "../qtconnectivityglobal.h" + +#include <qbluetoothaddress.h> +#include <qbluetoothuuid.h> + +#include <QIODevice> +#include <QtNetwork/QAbstractSocket> + +QT_BEGIN_HEADER + +class QBluetoothSocketPrivate; +class QBluetoothServiceInfo; + +class Q_CONNECTIVITY_EXPORT QBluetoothSocket : public QIODevice +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QBluetoothSocket) + + friend class QRfcommServer; + friend class QRfcommServerPrivate; + friend class QL2capServer; + friend class QL2capServerPrivate; + +public: + enum SocketType { + UnknownSocketType = -1, + L2capSocket, + RfcommSocket, + }; + + enum SocketState { + UnconnectedState = QAbstractSocket::UnconnectedState, + ServiceLookupState = QAbstractSocket::HostLookupState, + ConnectingState = QAbstractSocket::ConnectingState, + ConnectedState = QAbstractSocket::ConnectedState, + BoundState = QAbstractSocket::BoundState, + ClosingState = QAbstractSocket::ClosingState, + ListeningState = QAbstractSocket::ListeningState, + }; + + enum SocketError { + NoSocketError = -2, + UnknownSocketError = QAbstractSocket::UnknownSocketError, + ConnectionRefusedError = QAbstractSocket::ConnectionRefusedError, + RemoteHostClosedError = QAbstractSocket::RemoteHostClosedError, + HostNotFoundError = QAbstractSocket::HostNotFoundError, + ServiceNotFoundError = QAbstractSocket::SocketAddressNotAvailableError, + NetworkError = QAbstractSocket::NetworkError + }; + + explicit QBluetoothSocket(SocketType socketType, QObject *parent = 0); // create socket of type socketType + QBluetoothSocket(QObject *parent = 0); // create a blank socket + virtual ~QBluetoothSocket(); + + void abort(); + virtual void close(); + + bool isSequential() const; + + virtual qint64 bytesAvailable() const; + virtual qint64 bytesToWrite() const; + + virtual bool canReadLine() const; + + void connectToService(const QBluetoothServiceInfo &service, OpenMode openMode = ReadWrite); + void connectToService(const QBluetoothAddress &address, const QBluetoothUuid &uuid, OpenMode openMode = ReadWrite); + void connectToService(const QBluetoothAddress &address, quint16 port, OpenMode openMode = ReadWrite); + void disconnectFromService(); + + //bool flush(); + //bool isValid() const; + + QString localName() const; + QBluetoothAddress localAddress() const; + quint16 localPort() const; + + QString peerName() const; + QBluetoothAddress peerAddress() const; + quint16 peerPort() const; + //QBluetoothServiceInfo peerService() const; + + //qint64 readBufferSize() const; + //void setReadBufferSize(qint64 size); + + bool setSocketDescriptor(int socketDescriptor, SocketType socketType, + SocketState socketState = ConnectedState, + OpenMode openMode = ReadWrite); + int socketDescriptor() const; + + SocketType socketType() const; + SocketState state() const; + SocketError error() const; + QString errorString() const; + + //bool waitForConnected(int msecs = 30000); + //bool waitForDisconnected(int msecs = 30000); + //virtual bool waitForReadyRead(int msecs = 30000); + +Q_SIGNALS: + void connected(); + void disconnected(); + void error(QBluetoothSocket::SocketError error); + void stateChanged(QBluetoothSocket::SocketState state); + +protected: + virtual qint64 readData(char *data, qint64 maxSize); + virtual qint64 writeData(const char *data, qint64 maxSize); + + void setSocketState(SocketState state); + void setSocketError(SocketError error); + + void doDeviceDiscovery(const QBluetoothServiceInfo &service, OpenMode openMode); + +private Q_SLOTS: + void serviceDiscovered(const QBluetoothServiceInfo &service); + void discoveryFinished(); + + +protected: + QBluetoothSocketPrivate *d_ptr; + +private: + Q_PRIVATE_SLOT(d_func(), void _q_readNotify()) + Q_PRIVATE_SLOT(d_func(), void _q_writeNotify()) +#ifdef QT_SYMBIAN_BLUETOOTH + Q_PRIVATE_SLOT(d_func(), void _q_startReceive()) +#endif //QT_SYMBIAN_BLUETOOTH +}; + +#ifndef QT_NO_DEBUG_STREAM +Q_CONNECTIVITY_EXPORT QDebug operator<<(QDebug, QBluetoothSocket::SocketError); +Q_CONNECTIVITY_EXPORT QDebug operator<<(QDebug, QBluetoothSocket::SocketState); +#endif + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/qbluetoothsocket_bluez.cpp b/src/bluetooth/qbluetoothsocket_bluez.cpp new file mode 100644 index 00000000..78c0d995 --- /dev/null +++ b/src/bluetooth/qbluetoothsocket_bluez.cpp @@ -0,0 +1,549 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothsocket.h" +#include "qbluetoothsocket_p.h" + +#include "bluez/manager_p.h" +#include "bluez/adapter_p.h" +#include "bluez/device_p.h" + +#include <qplatformdefs.h> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/rfcomm.h> +#include <bluetooth/l2cap.h> + +#include <errno.h> +#include <unistd.h> +#include <string.h> + +#include <QtCore/QSocketNotifier> + +QBluetoothSocketPrivate::QBluetoothSocketPrivate() + : socket(-1), + socketType(QBluetoothSocket::UnknownSocketType), + state(QBluetoothSocket::UnconnectedState), + readNotifier(0), + connectWriteNotifier(0), + connecting(false), + discoveryAgent(0) +{ +} + +QBluetoothSocketPrivate::~QBluetoothSocketPrivate() +{ + delete readNotifier; + readNotifier = 0; + delete connectWriteNotifier; + connectWriteNotifier = 0; +} + +bool QBluetoothSocketPrivate::ensureNativeSocket(QBluetoothSocket::SocketType type) +{ + if (socket != -1) { + if (socketType == type) + return true; + + delete readNotifier; + readNotifier = 0; + delete connectWriteNotifier; + connectWriteNotifier = 0; + QT_CLOSE(socket); + } + + socketType = type; + + switch (type) { + case QBluetoothSocket::L2capSocket: + socket = ::socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + break; + case QBluetoothSocket::RfcommSocket: + socket = ::socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); + break; + default: + socket = -1; + } + + if (socket == -1) + return false; + + int flags = fcntl(socket, F_GETFL, 0); + fcntl(socket, F_SETFL, flags | O_NONBLOCK); + + Q_Q(QBluetoothSocket); + readNotifier = new QSocketNotifier(socket, QSocketNotifier::Read); + QObject::connect(readNotifier, SIGNAL(activated(int)), q, SLOT(_q_readNotify())); + connectWriteNotifier = new QSocketNotifier(socket, QSocketNotifier::Write, q); + QObject::connect(connectWriteNotifier, SIGNAL(activated(int)), q, SLOT(_q_writeNotify())); + + connectWriteNotifier->setEnabled(false); + readNotifier->setEnabled(false); + + + return true; +} + +void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address, quint16 port, QIODevice::OpenMode openMode) +{ + Q_Q(QBluetoothSocket); + Q_UNUSED(openMode); + int result = -1; + + if (socketType == QBluetoothSocket::RfcommSocket) { + sockaddr_rc addr; + + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + addr.rc_channel = port; + + convertAddress(address.toUInt64(), addr.rc_bdaddr.b); + + connectWriteNotifier->setEnabled(true); + readNotifier->setEnabled(true);QString(); + + result = ::connect(socket, (sockaddr *)&addr, sizeof(addr)); + } else if (socketType == QBluetoothSocket::L2capSocket) { + sockaddr_l2 addr; + + memset(&addr, 0, sizeof(addr)); + addr.l2_family = AF_BLUETOOTH; + addr.l2_psm = port; + + convertAddress(address.toUInt64(), addr.l2_bdaddr.b); + + connectWriteNotifier->setEnabled(true); + readNotifier->setEnabled(true); + + result = ::connect(socket, (sockaddr *)&addr, sizeof(addr)); + } + + if (result >= 0 || (result == -1 && errno == EINPROGRESS)) { + connecting = true; + q->setSocketState(QBluetoothSocket::ConnectingState); + } else { + errorString = QString::fromLocal8Bit(strerror(errno)); + q->setSocketError(QBluetoothSocket::UnknownSocketError); + } +} + +void QBluetoothSocketPrivate::_q_writeNotify() +{ + Q_Q(QBluetoothSocket); + if(connecting && state == QBluetoothSocket::ConnectingState){ + int errorno, len; + len = sizeof(errorno); + ::getsockopt(socket, SOL_SOCKET, SO_ERROR, &errorno, (socklen_t*)&len); + if(errorno) { + errorString = QString::fromLocal8Bit(strerror(errorno)); + emit q->error(QBluetoothSocket::UnknownSocketError); + return; + } + + q->setSocketState(QBluetoothSocket::ConnectedState); + emit q->connected(); + + connectWriteNotifier->setEnabled(false); + connecting = false; + } + else { + if (txBuffer.size() == 0) { + connectWriteNotifier->setEnabled(false); + return; + } + + char buf[1024]; + Q_Q(QBluetoothSocket); + + int size = txBuffer.read(buf, 1024); + + if (::write(socket, buf, size) != size) { + socketError = QBluetoothSocket::NetworkError; + emit q->error(socketError); + } + else { + emit q->bytesWritten(size); + } + + if (txBuffer.size()) { + connectWriteNotifier->setEnabled(true); + } + else if (state == QBluetoothSocket::ClosingState) { + connectWriteNotifier->setEnabled(false); + this->close(); + } + } +} + +// TODO: move to private backend? + +void QBluetoothSocketPrivate::_q_readNotify() +{ + Q_Q(QBluetoothSocket); + char *writePointer = buffer.reserve(QPRIVATELINEARBUFFER_BUFFERSIZE); +// qint64 readFromDevice = q->readData(writePointer, QPRIVATELINEARBUFFER_BUFFERSIZE); + int readFromDevice = ::read(socket, writePointer, QPRIVATELINEARBUFFER_BUFFERSIZE); + if(readFromDevice <= 0){ + int errsv = errno; + readNotifier->setEnabled(false); + connectWriteNotifier->setEnabled(false); + errorString = QString::fromLocal8Bit(strerror(errsv)); + qDebug() << Q_FUNC_INFO << socket << "error:" << readFromDevice << errorString; + if(errsv == EHOSTDOWN) + emit q->error(QBluetoothSocket::HostNotFoundError); + else + emit q->error(QBluetoothSocket::UnknownSocketError); + + q->disconnectFromService(); + q->setSocketState(QBluetoothSocket::UnconnectedState); + } + else { + buffer.chop(QPRIVATELINEARBUFFER_BUFFERSIZE - (readFromDevice < 0 ? 0 : readFromDevice)); + + emit q->readyRead(); + } +} + +void QBluetoothSocketPrivate::abort() +{ + delete readNotifier; + readNotifier = 0; + delete connectWriteNotifier; + connectWriteNotifier = 0; + + // We don't transition through Closing for abort, so + // we don't call disconnectFromService or + // QBluetoothSocket::close + QT_CLOSE(socket); + + Q_Q(QBluetoothSocket); + emit q->disconnected(); +} + +QString QBluetoothSocketPrivate::localName() const +{ + if (!m_localName.isEmpty()) + return m_localName; + + const QBluetoothAddress address = localAddress(); + if (address.isNull()) + return QString(); + + OrgBluezManagerInterface manager(QLatin1String("org.bluez"), QLatin1String("/"), + QDBusConnection::systemBus()); + + QDBusPendingReply<QDBusObjectPath> reply = manager.FindAdapter(address.toString()); + reply.waitForFinished(); + if (reply.isError()) + return QString(); + + OrgBluezAdapterInterface adapter(QLatin1String("org.bluez"), reply.value().path(), + QDBusConnection::systemBus()); + + QDBusPendingReply<QVariantMap> properties = adapter.GetProperties(); + properties.waitForFinished(); + if (properties.isError()) + return QString(); + + m_localName = properties.value().value(QLatin1String("Name")).toString(); + + return m_localName; +} + +QBluetoothAddress QBluetoothSocketPrivate::localAddress() const +{ + if (socketType == QBluetoothSocket::RfcommSocket) { + sockaddr_rc addr; + socklen_t addrLength = sizeof(addr); + + if (::getsockname(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0) { + quint64 bdaddr; + convertAddress(addr.rc_bdaddr.b, bdaddr); + return QBluetoothAddress(bdaddr); + } + } else if (socketType == QBluetoothSocket::L2capSocket) { + sockaddr_l2 addr; + socklen_t addrLength = sizeof(addr); + + if (::getsockname(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0) { + quint64 bdaddr; + convertAddress(addr.l2_bdaddr.b, bdaddr); + return QBluetoothAddress(bdaddr); + } + } + + return QBluetoothAddress(); +} + +quint16 QBluetoothSocketPrivate::localPort() const +{ + if (socketType == QBluetoothSocket::RfcommSocket) { + sockaddr_rc addr; + socklen_t addrLength = sizeof(addr); + + if (::getsockname(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0) + return addr.rc_channel; + } else if (socketType == QBluetoothSocket::L2capSocket) { + sockaddr_l2 addr; + socklen_t addrLength = sizeof(addr); + + if (::getsockname(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0) + return addr.l2_psm; + } + + return 0; +} + +QString QBluetoothSocketPrivate::peerName() const +{ + if (!m_peerName.isEmpty()) + return m_peerName; + + quint64 bdaddr; + + if (socketType == QBluetoothSocket::RfcommSocket) { + sockaddr_rc addr; + socklen_t addrLength = sizeof(addr); + + if (::getpeername(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) < 0) + return QString(); + + convertAddress(addr.rc_bdaddr.b, bdaddr); + } else if (socketType == QBluetoothSocket::L2capSocket) { + sockaddr_l2 addr; + socklen_t addrLength = sizeof(addr); + + if (::getpeername(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) < 0) + return QString(); + + convertAddress(addr.l2_bdaddr.b, bdaddr); + } else { + qWarning("peerName() called on socket of known type"); + return QString(); + } + + const QString address = QBluetoothAddress(bdaddr).toString(); + + OrgBluezManagerInterface manager(QLatin1String("org.bluez"), QLatin1String("/"), + QDBusConnection::systemBus()); + + QDBusPendingReply<QDBusObjectPath> reply = manager.DefaultAdapter(); + reply.waitForFinished(); + if (reply.isError()) + return QString(); + + OrgBluezAdapterInterface adapter(QLatin1String("org.bluez"), reply.value().path(), + QDBusConnection::systemBus()); + + QDBusPendingReply<QDBusObjectPath> deviceObjectPath = adapter.CreateDevice(address); + deviceObjectPath.waitForFinished(); + if (deviceObjectPath.isError()) { + if (deviceObjectPath.error().name() != QLatin1String("org.bluez.Error.AlreadyExists")) + return QString(); + + deviceObjectPath = adapter.FindDevice(address); + deviceObjectPath.waitForFinished(); + if (deviceObjectPath.isError()) + return QString(); + } + + OrgBluezDeviceInterface device(QLatin1String("org.bluez"), deviceObjectPath.value().path(), + QDBusConnection::systemBus()); + + QDBusPendingReply<QVariantMap> properties = device.GetProperties(); + properties.waitForFinished(); + if (properties.isError()) + return QString(); + + m_peerName = properties.value().value(QLatin1String("Alias")).toString(); + + return m_peerName; +} + +QBluetoothAddress QBluetoothSocketPrivate::peerAddress() const +{ + if (socketType == QBluetoothSocket::RfcommSocket) { + sockaddr_rc addr; + socklen_t addrLength = sizeof(addr); + + if (::getpeername(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0) { + quint64 bdaddr; + convertAddress(addr.rc_bdaddr.b, bdaddr); + return QBluetoothAddress(bdaddr); + } + } else if (socketType == QBluetoothSocket::L2capSocket) { + sockaddr_l2 addr; + socklen_t addrLength = sizeof(addr); + + if (::getpeername(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0) { + quint64 bdaddr; + convertAddress(addr.l2_bdaddr.b, bdaddr); + return QBluetoothAddress(bdaddr); + } + } + + return QBluetoothAddress(); +} + +quint16 QBluetoothSocketPrivate::peerPort() const +{ + if (socketType == QBluetoothSocket::RfcommSocket) { + sockaddr_rc addr; + socklen_t addrLength = sizeof(addr); + + if (::getpeername(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0) + return addr.rc_channel; + } else if (socketType == QBluetoothSocket::L2capSocket) { + sockaddr_l2 addr; + socklen_t addrLength = sizeof(addr); + + if (::getpeername(socket, reinterpret_cast<sockaddr *>(&addr), &addrLength) == 0) + return addr.l2_psm; + } + + return 0; +} + +qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize) +{ + Q_Q(QBluetoothSocket); + if (q->openMode() & QIODevice::Unbuffered) { + if (::write(socket, data, maxSize) != maxSize) { + socketError = QBluetoothSocket::NetworkError; + emit q->error(socketError); + } + + emit q->bytesWritten(maxSize); + + return maxSize; + } + else { + + if(!connectWriteNotifier) + return 0; + + if(txBuffer.size() == 0) { + connectWriteNotifier->setEnabled(true); + QMetaObject::invokeMethod(q, "_q_writeNotify", Qt::QueuedConnection); + } + + char *txbuf = txBuffer.reserve(maxSize); + memcpy(txbuf, data, maxSize); + + return maxSize; + } +} + +qint64 QBluetoothSocketPrivate::readData(char *data, qint64 maxSize) +{ + if(!buffer.isEmpty()){ + int i = buffer.read(data, maxSize); + return i; + + } + return 0; +} + +void QBluetoothSocketPrivate::close() +{ + Q_Q(QBluetoothSocket); + + // Only go through closing if the socket was fully opened + if(state == QBluetoothSocket::ConnectedState) + q->setSocketState(QBluetoothSocket::ClosingState); + + if(txBuffer.size() > 0 && + state == QBluetoothSocket::ClosingState){ + connectWriteNotifier->setEnabled(true); + } + else { + + delete readNotifier; + readNotifier = 0; + delete connectWriteNotifier; + connectWriteNotifier = 0; + + // We are disconnected now, so go to unconnected. + q->setSocketState(QBluetoothSocket::UnconnectedState); + emit q->disconnected(); + ::close(socket); + } + +} + +bool QBluetoothSocketPrivate::setSocketDescriptor(int socketDescriptor, QBluetoothSocket::SocketType socketType_, + QBluetoothSocket::SocketState socketState, QBluetoothSocket::OpenMode openMode) +{ + Q_Q(QBluetoothSocket); + delete readNotifier; + readNotifier = 0; + delete connectWriteNotifier; + connectWriteNotifier = 0; + + socketType = socketType_; + socket = socketDescriptor; + + // ensure that O_NONBLOCK is set on new connections. + int flags = fcntl(socket, F_GETFL, 0); + if (!(flags & O_NONBLOCK)) + fcntl(socket, F_SETFL, flags | O_NONBLOCK); + + readNotifier = new QSocketNotifier(socket, QSocketNotifier::Read); + QObject::connect(readNotifier, SIGNAL(activated(int)), q, SLOT(_q_readNotify())); + connectWriteNotifier = new QSocketNotifier(socket, QSocketNotifier::Write, q); + QObject::connect(connectWriteNotifier, SIGNAL(activated(int)), q, SLOT(_q_writeNotify())); + + q->setSocketState(socketState); + q->setOpenMode(openMode); + + return true; +} + +int QBluetoothSocketPrivate::socketDescriptor() const +{ + return socket; +} + +qint64 QBluetoothSocketPrivate::bytesAvailable() const +{ + return buffer.size(); +} + diff --git a/src/bluetooth/qbluetoothsocket_p.cpp b/src/bluetooth/qbluetoothsocket_p.cpp new file mode 100644 index 00000000..3a893799 --- /dev/null +++ b/src/bluetooth/qbluetoothsocket_p.cpp @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothsocket.h" +#include "qbluetoothsocket_p.h" + +QBluetoothSocketPrivate::QBluetoothSocketPrivate() +{ +} + +QBluetoothSocketPrivate::~QBluetoothSocketPrivate() +{ +} + +bool QBluetoothSocketPrivate::ensureNativeSocket(QBluetoothSocket::SocketType type) +{ + return false; +} + +void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address, quint16 port, QIODevice::OpenMode openMode) +{ + Q_UNUSED(openMode); + Q_UNUSED(address); + Q_UNUSED(port); +} + +void QBluetoothSocketPrivate::_q_writeNotify() +{ +} + +void QBluetoothSocketPrivate::_q_readNotify() +{ +} + +void QBluetoothSocketPrivate::abort() +{ +} + +QString QBluetoothSocketPrivate::localName() const +{ + return QString(); +} + +QBluetoothAddress QBluetoothSocketPrivate::localAddress() const +{ + return QBluetoothAddress(); +} + +quint16 QBluetoothSocketPrivate::localPort() const +{ + return 0; +} + +QString QBluetoothSocketPrivate::peerName() const +{ + return QString(); +} + +QBluetoothAddress QBluetoothSocketPrivate::peerAddress() const +{ + return QBluetoothAddress(); +} + +quint16 QBluetoothSocketPrivate::peerPort() const +{ + return 0; +} + +qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize) +{ + Q_UNUSED(data); + Q_UNUSED(maxSize); + return 0; +} + +qint64 QBluetoothSocketPrivate::readData(char *data, qint64 maxSize) +{ + Q_UNUSED(data); + Q_UNUSED(maxSize); + return 0; +} + +void QBluetoothSocketPrivate::close() +{ +} + +bool QBluetoothSocketPrivate::setSocketDescriptor(int socketDescriptor, QBluetoothSocket::SocketType socketType, + QBluetoothSocket::SocketState socketState, QBluetoothSocket::OpenMode openMode) +{ + Q_UNUSED(socketDescriptor); + Q_UNUSED(socketType) + Q_UNUSED(socketState); + Q_UNUSED(openMode); + return false; +} + +int QBluetoothSocketPrivate::socketDescriptor() const +{ + return 0; +} + +qint64 QBluetoothSocketPrivate::bytesAvailable() const +{ + return 0; +} + diff --git a/src/bluetooth/qbluetoothsocket_p.h b/src/bluetooth/qbluetoothsocket_p.h new file mode 100644 index 00000000..302cf638 --- /dev/null +++ b/src/bluetooth/qbluetoothsocket_p.h @@ -0,0 +1,209 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHSOCKET_P_H +#define QBLUETOOTHSOCKET_P_H + +#include "qbluetoothsocket.h" + +#ifndef QPRIVATELINEARBUFFER_BUFFERSIZE +#define QPRIVATELINEARBUFFER_BUFFERSIZE Q_INT64_C(16384) +#endif +#include "../qprivatelinearbuffer_p.h" + +#include <QtGlobal> + +#ifdef QT_SYMBIAN_BLUETOOTH +#include <es_sock.h> +#include <bt_sock.h> +#include <bttypes.h> +#endif + +QT_FORWARD_DECLARE_CLASS(QSocketNotifier) + +QT_BEGIN_HEADER + +class QBluetoothServiceDiscoveryAgent; + +class QSocketServerPrivate +{ +public: + QSocketServerPrivate(); + ~QSocketServerPrivate(); + +#ifdef QT_SYMBIAN_BLUETOOTH + RSocketServ socketServer; +#endif +}; + + + +class QBluetoothSocket; +class QBluetoothServiceDiscoveryAgent; + +class QBluetoothSocketPrivate +#ifdef QT_SYMBIAN_BLUETOOTH +: public MBluetoothSocketNotifier +#endif +{ + Q_DECLARE_PUBLIC(QBluetoothSocket) +public: + + QBluetoothSocketPrivate(); + ~QBluetoothSocketPrivate(); + + void connectToService(const QBluetoothAddress &address, quint16 port, QIODevice::OpenMode openMode); + + bool ensureNativeSocket(QBluetoothSocket::SocketType type); + + QString localName() const; + QBluetoothAddress localAddress() const; + quint16 localPort() const; + + QString peerName() const; + QBluetoothAddress peerAddress() const; + quint16 peerPort() const; + //QBluetoothServiceInfo peerService() const; + + void abort(); + void close(); + + //qint64 readBufferSize() const; + //void setReadBufferSize(qint64 size); + + qint64 writeData(const char *data, qint64 maxSize); + qint64 readData(char *data, qint64 maxSize); + + bool setSocketDescriptor(int socketDescriptor, QBluetoothSocket::SocketType socketType, + QBluetoothSocket::SocketState socketState = QBluetoothSocket::ConnectedState, + QBluetoothSocket::OpenMode openMode = QBluetoothSocket::ReadWrite); + int socketDescriptor() const; + + qint64 bytesAvailable() const; + +#ifdef QT_SYMBIAN_BLUETOOTH + void _q_startReceive(); + void startReceive(); + void startServerSideReceive(); + void receive(); + bool ensureBlankNativeSocket(QBluetoothSocket::SocketType type); + bool tryToSend(); + + /* MBluetoothSocketNotifier virtual functions */ + void HandleActivateBasebandEventNotifierCompleteL(TInt aErr, TBTBasebandEventNotification& aEventNotification); + void HandleAcceptCompleteL(TInt aErr); + void HandleConnectCompleteL(TInt aErr); + void HandleIoctlCompleteL(TInt aErr); + void HandleReceiveCompleteL(TInt aErr); + void HandleSendCompleteL(TInt aErr); + void HandleShutdownCompleteL(TInt aErr); +#endif + +public: + QPrivateLinearBuffer buffer; + QPrivateLinearBuffer txBuffer; + int socket; + QBluetoothSocket::SocketType socketType; + QBluetoothSocket::SocketState state; + QBluetoothSocket::SocketError socketError; + QSocketNotifier *readNotifier; + QSocketNotifier *connectWriteNotifier; + bool connecting; + + QBluetoothServiceDiscoveryAgent *discoveryAgent; + QBluetoothSocket::OpenMode openMode; + + +// QByteArray rxBuffer; +// qint64 rxOffset; + QString errorString; + +#ifdef QT_SYMBIAN_BLUETOOTH + CBluetoothSocket *iSocket; + TPtr8 rxDescriptor; + TPtrC8 txDescriptor; + QByteArray txArray; + TSockXfrLength rxLength; + TInt recvMTU; + TInt txMTU; + char* bufPtr; + bool transmitting; + quint64 writeSize; +#endif + + // private slots + void _q_readNotify(); + void _q_writeNotify(); + void _q_serviceDiscovered(const QBluetoothServiceInfo &service); + void _q_discoveryFinished(); + +protected: + QBluetoothSocket *q_ptr; + +private: + mutable QString m_localName; + mutable QString m_peerName; +}; + + +static inline void convertAddress(quint64 from, quint8 (&to)[6]) +{ + to[0] = (from >> 0) & 0xff; + to[1] = (from >> 8) & 0xff; + to[2] = (from >> 16) & 0xff; + to[3] = (from >> 24) & 0xff; + to[4] = (from >> 32) & 0xff; + to[5] = (from >> 40) & 0xff; +} + +static inline void convertAddress(quint8 (&from)[6], quint64 &to) +{ + to = (quint64(from[0]) << 0) | + (quint64(from[1]) << 8) | + (quint64(from[2]) << 16) | + (quint64(from[3]) << 24) | + (quint64(from[4]) << 32) | + (quint64(from[5]) << 40); +} + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/qbluetoothsocket_symbian.cpp b/src/bluetooth/qbluetoothsocket_symbian.cpp new file mode 100644 index 00000000..d17a6f5c --- /dev/null +++ b/src/bluetooth/qbluetoothsocket_symbian.cpp @@ -0,0 +1,591 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothsocket_p.h" +#include "qbluetoothsocket.h" +#include "qbluetoothlocaldevice_p.h" +#include "symbian/utils_symbian_p.h" + +#include <QCoreApplication> + +#include <QDebug> + +#include <limits.h> +#include <bt_sock.h> +#include <es_sock.h> + +Q_GLOBAL_STATIC(QSocketServerPrivate, getSocketServer) + +QBluetoothSocketPrivate::QBluetoothSocketPrivate() + : socket(0) + , socketType(QBluetoothSocket::UnknownSocketType) + , state(QBluetoothSocket::UnconnectedState) + , readNotifier(0) + , connectWriteNotifier(0) + , discoveryAgent(0) + , iSocket(0) + , rxDescriptor(0, 0) + , txDescriptor(0, 0) + , recvMTU(0) + , txMTU(0) + , transmitting(false) + , writeSize(0) +{ +} + +QBluetoothSocketPrivate::~QBluetoothSocketPrivate() +{ + delete iSocket; +} + +void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address, quint16 port, QIODevice::OpenMode openMode) +{ + Q_Q(QBluetoothSocket); + Q_UNUSED(openMode); + + TBTSockAddr a; + + if(address.isNull()) + { + socketError = QBluetoothSocket::UnknownSocketError; + emit q->error(socketError); + return; + } + TInt err = KErrNone; + a.SetPort(port); + // Trap TBTDevAddr constructor which may panic + TRAP(err, a.SetBTAddr(TBTDevAddr(address.toUInt64()))); + if(err == KErrNone) + err = iSocket->Connect(a); + if (err == KErrNone) { + q->setSocketState(QBluetoothSocket::ConnectingState); + } else { + socketError = QBluetoothSocket::UnknownSocketError; + emit q->error(socketError); + } +} + +bool QBluetoothSocketPrivate::ensureNativeSocket(QBluetoothSocket::SocketType type) +{ + if (iSocket) { + if (socketType == type) + { + return true; + } + else + { + delete iSocket; + iSocket = 0; + } + } + + socketType = type; + + switch (type) { + case QBluetoothSocket::L2capSocket: { + TRAPD(err, iSocket = CBluetoothSocket::NewL(*this, getSocketServer()->socketServer, _L("L2CAP"))); + Q_UNUSED(err); + break; + } + case QBluetoothSocket::RfcommSocket: { + TRAPD(err, iSocket = CBluetoothSocket::NewL(*this, getSocketServer()->socketServer, _L("RFCOMM"))); + Q_UNUSED(err); + break; + } + default: + iSocket = 0; + } + + if (iSocket) + return true; + else + return false; +} + +bool QBluetoothSocketPrivate::ensureBlankNativeSocket(QBluetoothSocket::SocketType type) +{ + if (iSocket) { + delete iSocket; + iSocket = 0; + } + socketType = type; + TRAPD(err, iSocket = CBluetoothSocket::NewL(*this, getSocketServer()->socketServer)); + Q_UNUSED(err); + if(iSocket) + return true; + else + return false; +} + +void QBluetoothSocketPrivate::startReceive() +{ + Q_Q(QBluetoothSocket); + if (!iSocket || state != QBluetoothSocket::ConnectedState) { + emit q->error(QBluetoothSocket::UnknownSocketError); + return; + } + TInt err = iSocket->GetOpt(KL2CAPInboundMTU, KSolBtL2CAP, recvMTU); + if(err != KErrNone) + { + emit q->error(QBluetoothSocket::UnknownSocketError); + return; + } + err = iSocket->GetOpt(KL2CAPNegotiatedOutboundMTU, KSolBtL2CAP, txMTU); + if(err != KErrNone) + { + emit q->error(QBluetoothSocket::UnknownSocketError); + return; + } + bufPtr = buffer.reserve(recvMTU); + // enable automatic power saving mode + iSocket->SetAutomaticSniffMode(ETrue); + // enable link down and link error notifications for proper disconnection + err = iSocket->ActivateBasebandEventNotifier(ENotifyPhysicalLinkDown |ENotifyPhysicalLinkError ); + if(err != KErrNone) + { + emit q->error(QBluetoothSocket::UnknownSocketError); + return; + } + receive(); +} + +void QBluetoothSocketPrivate::receive() +{ + Q_Q(QBluetoothSocket); + TInt err = KErrNone; + + if(!iSocket || bufPtr == 0 || recvMTU == 0 || socketType < 0 || state != QBluetoothSocket::ConnectedState) + { + emit q->error(QBluetoothSocket::UnknownSocketError); + return; + } + + TRAP(err, rxDescriptor.Set(reinterpret_cast<unsigned char *>(bufPtr), 0,recvMTU)); + if(err != KErrNone) + { + emit q->error(QBluetoothSocket::UnknownSocketError); + return; + } + if (socketType == QBluetoothSocket::RfcommSocket) { + // cancel any pending recv operation + iSocket->CancelRecv(); + err = iSocket->RecvOneOrMore(rxDescriptor, 0, rxLength); + if (err != KErrNone) { + socketError = QBluetoothSocket::UnknownSocketError; + emit q->error(socketError); + } + } else if (socketType == QBluetoothSocket::L2capSocket) { + // cancel any pending read operation + iSocket->CancelRead(); + err = iSocket->Read(rxDescriptor); + if (err != KErrNone) { + socketError = QBluetoothSocket::UnknownSocketError; + emit q->error(socketError); + } + } + } + +void QBluetoothSocketPrivate::HandleAcceptCompleteL(TInt aErr) +{ + qDebug() << __PRETTY_FUNCTION__ << ">> aErr=" << aErr; + Q_Q(QBluetoothSocket); + if(aErr != KErrNone) + { + socketError = QBluetoothSocket::UnknownSocketError; + emit q->error(socketError); + return; + } + emit q->connected(); +} + +void QBluetoothSocketPrivate::HandleActivateBasebandEventNotifierCompleteL(TInt aErr, TBTBasebandEventNotification& aEventNotification) +{ + qDebug() << __PRETTY_FUNCTION__; + Q_Q(QBluetoothSocket); + if(aErr != KErrNone) + { + socketError = QBluetoothSocket::UnknownSocketError; + emit q->error(socketError); + } + if(ENotifyPhysicalLinkDown & aEventNotification.EventType() || ENotifyPhysicalLinkError & aEventNotification.EventType()) + { + q->setSocketState(QBluetoothSocket::ClosingState); + emit q->disconnected(); + } +} + +void QBluetoothSocketPrivate::HandleConnectCompleteL(TInt aErr) +{ + qDebug() << __PRETTY_FUNCTION__ << ">> aErr=" << aErr; + Q_Q(QBluetoothSocket); + if (aErr == KErrNone) { + q->setSocketState(QBluetoothSocket::ConnectedState); + + emit q->connected(); + + startReceive(); + } else { + q->setSocketState(QBluetoothSocket::UnconnectedState); + + switch (aErr) { + case KErrCouldNotConnect: + socketError = QBluetoothSocket::ConnectionRefusedError; + break; + default: + qDebug() << __PRETTY_FUNCTION__ << aErr; + socketError = QBluetoothSocket::UnknownSocketError; + } + emit q->error(socketError); + } +} + +void QBluetoothSocketPrivate::HandleIoctlCompleteL(TInt aErr) +{ + qDebug() << __PRETTY_FUNCTION__; + Q_Q(QBluetoothSocket); + if(aErr != KErrNone) + { + socketError = QBluetoothSocket::UnknownSocketError; + emit q->error(socketError); + } +} + +void QBluetoothSocketPrivate::HandleReceiveCompleteL(TInt aErr) +{ + Q_Q(QBluetoothSocket); + if (aErr == KErrNone) { + if(buffer.size() == 0) + bufPtr = buffer.reserve(recvMTU); + if(bufPtr <= 0) + { + socketError = QBluetoothSocket::UnknownSocketError; + emit q->error(socketError); + return; + } + buffer.chop(recvMTU - rxDescriptor.Length()); + emit q->readyRead(); + } else { + // ignore disconnection it will be handled in baseband notification + if(aErr != KErrDisconnected) + { + socketError = QBluetoothSocket::UnknownSocketError; + writeSize = 0; + emit q->error(socketError); + } + } +} + +void QBluetoothSocketPrivate::HandleSendCompleteL(TInt aErr) +{ + Q_Q(QBluetoothSocket); + transmitting = false; + if (aErr == KErrNone) { + txArray.remove(0, writeSize); + emit q->bytesWritten(writeSize); + if (state == QBluetoothSocket::ClosingState) + { + writeSize = 0; + q->close(); + } + else + { + if(!tryToSend()) + { + socketError = QBluetoothSocket::UnknownSocketError; + writeSize = 0; + emit q->error(socketError); + } + } + } else { + socketError = QBluetoothSocket::UnknownSocketError; + writeSize = 0; + emit q->error(socketError); + } +} + +void QBluetoothSocketPrivate::HandleShutdownCompleteL(TInt aErr) +{ + Q_Q(QBluetoothSocket); + // It doesn't matter if aErr is KErrNone or something else + // we consider the socket to be closed. + q->setSocketState(QBluetoothSocket::UnconnectedState); + transmitting = false; + writeSize = 0; + iSocket->AsyncDelete(); + emit q->disconnected(); +} + +QSocketServerPrivate::QSocketServerPrivate() +{ + /* connect to socket server */ + TInt result = socketServer.Connect(); + if (result != KErrNone) { + qWarning("%s: RSocketServ.Connect() failed with error %d", __PRETTY_FUNCTION__, result); + return; + } +} + +QSocketServerPrivate::~QSocketServerPrivate() +{ + if (socketServer.Handle() != 0) + socketServer.Close(); +} + +QString QBluetoothSocketPrivate::localName() const +{ + return QBluetoothLocalDevicePrivate::name(); +} + +QBluetoothAddress QBluetoothSocketPrivate::localAddress() const +{ + TBTSockAddr address; + if(!iSocket) + { + // need to return something anyway + return QBluetoothAddress(); + } + iSocket->LocalName(address); + return qTBTDevAddrToQBluetoothAddress(address.BTAddr()); +} + +quint16 QBluetoothSocketPrivate::localPort() const +{ + if(!iSocket) + { + // need to return something anyway + return 0; + } + return iSocket->LocalPort(); +} + +QString QBluetoothSocketPrivate::peerName() const +{ + RHostResolver resolver; + + if(getSocketServer()->socketServer.Handle()== 0 || !iSocket || state != QBluetoothSocket::ConnectedState ) + { + // need to return something anyway + return QString(); + } + TInt err = resolver.Open(getSocketServer()->socketServer, KBTAddrFamily, KBTLinkManager); + if (err==KErrNone) + { + TNameEntry nameEntry; + TBTSockAddr sockAddr; + iSocket->RemoteName(sockAddr); + TInquirySockAddr address(sockAddr); + address.SetBTAddr(sockAddr.BTAddr()); + address.SetAction(KHostResName|KHostResIgnoreCache); // ignore name stored in cache + err = resolver.GetByAddress(address, nameEntry); + if(err == KErrNone) + { + TNameRecord name = nameEntry(); + QString qString((QChar*)name.iName.Ptr(),name.iName.Length()); + m_peerName = qString; + } + } + resolver.Close(); + + if(err != KErrNone) + { + // What is best? return an empty string or return the MAC address? + // In Symbian if we can't get the remote name we usually replace it with the MAC address + // but since Bluez implementation return an empty string we do the same here. + return QString(); + } + + return m_peerName; +} + +QBluetoothAddress QBluetoothSocketPrivate::peerAddress() const +{ + TBTSockAddr address; + if(!iSocket) + { + // need to return something anyway + return QBluetoothAddress(); + } + iSocket->RemoteName(address); + return qTBTDevAddrToQBluetoothAddress(address.BTAddr()); +} + +quint16 QBluetoothSocketPrivate::peerPort() const +{ + TBTSockAddr address; + if(!iSocket) + { + // need to return something anyway + return 0; + } + iSocket->RemoteName(address); + return address.Port(); +} + +void QBluetoothSocketPrivate::close() +{ + Q_Q(QBluetoothSocket); + if(!iSocket || (state != QBluetoothSocket::ConnectedState && state != QBluetoothSocket::ListeningState)) + { + socketError = QBluetoothSocket::UnknownSocketError; + emit q->error(socketError); + return; + } + iSocket->CancelBasebandEventNotifier(); + q->setSocketState(QBluetoothSocket::ClosingState); + iSocket->Shutdown(RSocket::ENormal); +} + +void QBluetoothSocketPrivate::abort() +{ + Q_Q(QBluetoothSocket); + if(!iSocket) + { + socketError = QBluetoothSocket::UnknownSocketError; + emit q->error(socketError); + return; + } + iSocket->CancelWrite(); + transmitting = false; + writeSize = 0; + iSocket->CancelBasebandEventNotifier(); + iSocket->Shutdown(RSocket::EImmediate); + // force active object to run and shutdown socket. + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); +} + +qint64 QBluetoothSocketPrivate::readData(char *data, qint64 maxSize) +{ + Q_Q(QBluetoothSocket); + if(data == 0 || maxSize <= 0) + { + return -1; + } + qint64 size = buffer.read(data, maxSize); + QMetaObject::invokeMethod(q, "_q_startReceive", Qt::QueuedConnection); + return size; +} + +qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize) +{ + if(!iSocket || data == 0 || maxSize <= 0 || txMTU <= 0) { + return -1; + } + if (!txArray.isEmpty()) + { + txArray.append(QByteArray(data, maxSize)); + } + else + { + txArray = QByteArray(data, maxSize); + } + // we try to send the data to the remote device + if(tryToSend()) + { + // Warning : It doesn't mean the data have been sent + // to the remote device, it means that the data was + // at least stored in a local buffer. + return maxSize; + } + else + { + writeSize = 0; + return -1; + } +} + +void QBluetoothSocketPrivate::_q_readNotify() +{ +} + +void QBluetoothSocketPrivate::_q_writeNotify() +{ + +} + +bool QBluetoothSocketPrivate::setSocketDescriptor(int socketDescriptor, QBluetoothSocket::SocketType socketType, + QBluetoothSocket::SocketState socketState, QBluetoothSocket::OpenMode openMode) +{ + Q_UNUSED(socketDescriptor); + Q_UNUSED(socketType); + Q_UNUSED(socketState); + Q_UNUSED(openMode); + return false; +} + +void QBluetoothSocketPrivate::_q_startReceive() +{ + receive(); +} + +qint64 QBluetoothSocketPrivate::bytesAvailable() const +{ + return buffer.size(); +} + +bool QBluetoothSocketPrivate::tryToSend() +{ + if(txArray.isEmpty()) + return true; + + if(transmitting) + return transmitting; + + // we cannot write more than txMTU otherwise the extra data will just be lost + TInt dataLen = qMin(txArray.length(),txMTU); + + TRAPD(err, txDescriptor.Set(reinterpret_cast<const unsigned char *>(txArray.constData()),dataLen)); + if(err != KErrNone) + { + transmitting = false; + } + else + { + err = iSocket->Write(txDescriptor); + if (err != KErrNone) + { + transmitting = false; + } + writeSize = dataLen; + transmitting = true; + } + return transmitting; +} + diff --git a/src/bluetooth/qbluetoothtransfermanager.cpp b/src/bluetooth/qbluetoothtransfermanager.cpp new file mode 100644 index 00000000..a52f93df --- /dev/null +++ b/src/bluetooth/qbluetoothtransfermanager.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothtransfermanager.h" +#include "qbluetoothtransferrequest.h" + +/*! + \class QBluetoothTransferManager + \brief The QBluetoothTransferManager class allows the application to send data objects to other + devices. Currently implemented using OPP. + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity + \since 5.0 + + QBluetoothTransferManager uses OBEX to send get and put commands to remote devices. +*/ + +/*! + \enum QBluetoothTransferManager::Operation + + This enum describes the type of operation that a transfer request is for. + + \value GetOperation The get operation is used to retrieve an object from a remote device. Not implemented. + \value PutOperation The put operation is used to send an object to a remote device. +*/ + +/*! + \fn QBluetoothTransferReply *QBluetoothTransferManager::put(const QBluetoothTransferRequest &request, QIODevice *data) + + Sends the contents of \a data to the remote device \a request and returns a new + QBluetoothTransferReply, that can be used to track the request's progress. +*/ + + + +/*! + \fn void QBluetoothTransferManager::finished(QBluetoothTransferReply *reply) + + This signal is emitted when the transfer for \a reply finishes. +*/ + +/*! + Constructs a new QBluetoothTransferManager with \a parent. +*/ +QBluetoothTransferManager::QBluetoothTransferManager(QObject *parent) +: QObject(parent) +{ +} + +/*! + Destroys the QBluetoothTransferManager. +*/ +QBluetoothTransferManager::~QBluetoothTransferManager() +{ +} + + +#include "moc_qbluetoothtransfermanager.cpp" diff --git a/src/bluetooth/qbluetoothtransfermanager.h b/src/bluetooth/qbluetoothtransfermanager.h new file mode 100644 index 00000000..099fa940 --- /dev/null +++ b/src/bluetooth/qbluetoothtransfermanager.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHTRANSFERMANAGER_H +#define QBLUETOOTHTRANSFERMANAGER_H + +#include "../qtconnectivityglobal.h" +#include <qbluetoothaddress.h> + +#include <QtCore/QObject> + +QT_FORWARD_DECLARE_CLASS(QIODevice) + +QT_BEGIN_HEADER + +class QBluetoothTransferReply; +class QBluetoothTransferRequest; +class QBluetoothTranferManagerPrivate; + +class Q_CONNECTIVITY_EXPORT QBluetoothTransferManager : public QObject +{ + Q_OBJECT + +public: + enum Operation { + GetOperation, + PutOperation + }; + + explicit QBluetoothTransferManager(QObject *parent = 0); + ~QBluetoothTransferManager(); + + QBluetoothTransferReply *put(const QBluetoothTransferRequest &request, QIODevice *data); + +signals: + void finished(QBluetoothTransferReply *reply); + +}; + +QT_END_HEADER + +#endif // QBLUETOOTHTRANSFERMANAGER_H diff --git a/src/bluetooth/qbluetoothtransfermanager_bluez.cpp b/src/bluetooth/qbluetoothtransfermanager_bluez.cpp new file mode 100644 index 00000000..fba6cea0 --- /dev/null +++ b/src/bluetooth/qbluetoothtransfermanager_bluez.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothtransfermanager.h" +#include "qbluetoothtransferrequest.h" +#include "qbluetoothtransferreply.h" +#include "qbluetoothtransferreply_bluez_p.h" + +QBluetoothTransferReply *QBluetoothTransferManager::put(const QBluetoothTransferRequest &request, + QIODevice *data) +{ + + QBluetoothTransferReplyBluez *rep = new QBluetoothTransferReplyBluez(data); + + rep->setAddress(request.address()); + + connect(rep, SIGNAL(finished(QBluetoothTransferReply*)), this, SIGNAL(finished(QBluetoothTransferReply*))); + + rep->start(); + + return rep; +} diff --git a/src/bluetooth/qbluetoothtransfermanager_p.cpp b/src/bluetooth/qbluetoothtransfermanager_p.cpp new file mode 100644 index 00000000..77a85187 --- /dev/null +++ b/src/bluetooth/qbluetoothtransfermanager_p.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothtransfermanager.h" +#include "qbluetoothtransferrequest.h" +#include "qbluetoothtransferreply.h" + +QBluetoothTransferReply *QBluetoothTransferManager::put(const QBluetoothTransferRequest &request, + QIODevice *data) +{ + return 0; +} diff --git a/src/bluetooth/qbluetoothtransfermanager_symbian.cpp b/src/bluetooth/qbluetoothtransfermanager_symbian.cpp new file mode 100644 index 00000000..73828dcd --- /dev/null +++ b/src/bluetooth/qbluetoothtransfermanager_symbian.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothtransfermanager.h" +#include "qbluetoothtransferrequest.h" +#include "qbluetoothtransferreply.h" +#include "qbluetoothtransferreply_symbian_p.h" + +QBluetoothTransferReply *QBluetoothTransferManager::put(const QBluetoothTransferRequest &request, + QIODevice *data) +{ + QBluetoothTransferReplySymbian *reply = + new QBluetoothTransferReplySymbian(data, QBluetoothTransferManager::PutOperation); + + reply->setAddress(request.address()); + + connect(reply, SIGNAL(finished(QBluetoothTransferReply*)), this, SIGNAL(finished(QBluetoothTransferReply*))); + + reply->start(); + + return reply; +} diff --git a/src/bluetooth/qbluetoothtransferreply.cpp b/src/bluetooth/qbluetoothtransferreply.cpp new file mode 100644 index 00000000..e8af9707 --- /dev/null +++ b/src/bluetooth/qbluetoothtransferreply.cpp @@ -0,0 +1,217 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qbluetoothtransferreply.h" +#include "qbluetoothtransferreply_p.h" +#include "qbluetoothaddress.h" + +/*! + \class QBluetoothTransferReply + \brief The QBluetoothTransferReply class contains the data and headers for a request sent with + QBluetoothTranferManager. + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity + \since 5.0 + + In additional to a copy of the QBluetoothTransferRequest object used to create the request, + QBluetoothTransferReply contains the contents of the reply itself. + + QBluetoothTransferReply is a sequential-access QIODevice, which means that once data is read + from the object, it no longer kept by the device. It is therefore the application's + responsibility to keep this data if it needs to. Whenever more data is received and processed, + the readyRead() signal is emitted. + + The downloadProgress() signal is also emitted when data is received, but the number of bytes + contained in it may not represent the actual bytes received, if any transformation is done to + the contents (for example, decompressing and removing the protocol overhead). + + Even though QBluetoothTransferReply is a QIODevice connected to the contents of the reply, it + also emits the uploadProgress() signal, which indicates the progress of the upload for + operations that have such content. +*/ + +/*! + \enum QBluetoothTransferReply::TransferError + + This enum describes the type of error that occurred + + \value NoError No error. + \value UnknownError Unknown error, no better enum available + \value FileNotFoundError Unable to open the file specified + \value HostNotFoundError Unable to connect to the target host + \value UserCanceledTransferError User terminated the transfer +*/ + + + +/*! + \fn QBluetoothTransferReply::abort() + + Aborts this reply. +*/ +void QBluetoothTransferReply::abort() +{ + +} + +/*! + \fn void QBluetoothTransferReply::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) + + This signal is emitted whenever data is received. The \a bytesReceived parameter contains the + total number of bytes received so far out of \a bytesTotal expected for the entire transfer. +*/ + +/*! + \fn void QBluetoothTransferReply::finished(QBluetoothTransferReply *reply) + + This signal is emitted when the transfer is complete for \a reply. +*/ + +/*! + \fn void QBluetoothTransferReply::uploadProgress(qint64 bytesSent, qint64 bytesTotal) + + This signal is emitted whenever data is sent. The \a bytesSent parameter contains the total + number of bytes sent so far out of \a bytesTotal. +*/ + +/*! + Constructs a new QBluetoothTransferReply with parent \a parent. +*/ +QBluetoothTransferReply::QBluetoothTransferReply(QObject *parent) +: QObject(parent), d_ptr(new QBluetoothTransferReplyPrivate) +{ + qRegisterMetaType<QBluetoothTransferReply*>("QBluetoothTransferReply"); +} + +/*! + Destroys the QBluetoothTransferReply object. +*/ +QBluetoothTransferReply::~QBluetoothTransferReply() +{ + delete d_ptr; +} + +/*! + Returns the attribute associated with the code \a code. If the attribute has not been set, it + returns an invalid QVariant. +*/ +QVariant QBluetoothTransferReply::attribute(QBluetoothTransferRequest::Attribute code) const +{ + Q_D(const QBluetoothTransferReply); + return d->m_attributes[code]; +} + +/*! + \fn bool QBluetoothTransferReply::isFinished() const + + Returns true if this reply has finished; otherwise returns false. +*/ + +/*! + \fn bool QBluetoothTransferReply::isRunning() const + + Returns true if this reply is running; otherwise returns false. +*/ + +/*! + Returns the QBluetoothTransferManager that was used to create this QBluetoothTransferReply + object. +*/ +QBluetoothTransferManager *QBluetoothTransferReply::manager() const +{ + Q_D(const QBluetoothTransferReply); + return d->m_manager; +} + +/*! + Returns the type of operation that this reply is for. +*/ +QBluetoothTransferManager::Operation QBluetoothTransferReply::operation() const +{ + Q_D(const QBluetoothTransferReply); + return d->m_operation; +} + +/*! + Sets the operation of this QBluetoothTransferReply to \a operation. +*/ +void QBluetoothTransferReply::setOperation(QBluetoothTransferManager::Operation operation) +{ + Q_D(QBluetoothTransferReply); + d->m_operation = operation; +} + +/*! + \fn QBluetoothTransferReply::setAttribute(QBluetoothTransferRequest::Attribute code, const QVariant &value) + + Set the attribute associated with the code \a code to the value \a value. +*/ +void QBluetoothTransferReply::setAttribute(QBluetoothTransferRequest::Attribute code, const QVariant &value) +{ + Q_D(QBluetoothTransferReply); + d->m_attributes.insert(code, value); +} + +/*! + \fn QBluetoothTransferReply::setManager(QBluetoothTransferManager *manager) + + Set the reply's manager to manager \a manager. +*/ + +void QBluetoothTransferReply::setManager(QBluetoothTransferManager *manager) +{ + Q_D(QBluetoothTransferReply); + d->m_manager = manager; +} + +/*! + \fn QString QBluetoothTransferReply::errorString() const + + String describing the error. Can be displayed to the user. +*/ + +QBluetoothTransferReplyPrivate::QBluetoothTransferReplyPrivate() +{ +} + +#include "moc_qbluetoothtransferreply.cpp" diff --git a/src/bluetooth/qbluetoothtransferreply.h b/src/bluetooth/qbluetoothtransferreply.h new file mode 100644 index 00000000..c09be812 --- /dev/null +++ b/src/bluetooth/qbluetoothtransferreply.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHTRANSFERREPLY_H +#define QBLUETOOTHTRANSFERREPLY_H + +#include <QtCore/QIODevice> + +#include <qbluetoothtransferrequest.h> +#include <qbluetoothtransfermanager.h> + +QT_BEGIN_HEADER + +class QBluetoothTransferReplyPrivate; + +class Q_CONNECTIVITY_EXPORT QBluetoothTransferReply : public QObject +{ + Q_OBJECT + +public: + enum TransferError { + NoError = 0, + UnknownError, + FileNotFoundError, + HostNotFoundError, + UserCanceledTransferError + }; + + + ~QBluetoothTransferReply(); + + QVariant attribute(QBluetoothTransferRequest::Attribute code) const; + virtual bool isFinished() const = 0; + virtual bool isRunning() const = 0; + + QBluetoothTransferManager *manager() const; + + QBluetoothTransferManager::Operation operation() const; + + virtual TransferError error() const = 0; + virtual QString errorString() const = 0; + +public Q_SLOTS: + void abort(); + +Q_SIGNALS: + void downloadProgress(qint64 bytesReceived, qint64 bytesTotal); + void finished(QBluetoothTransferReply *); + void uploadProgress(qint64 bytesSent, qint64 bytesTotal); + +protected: + explicit QBluetoothTransferReply(QObject *parent = 0); + void setAttribute(QBluetoothTransferRequest::Attribute code, const QVariant &value); + void setOperation(QBluetoothTransferManager::Operation operation); + void setManager(QBluetoothTransferManager *manager); +// void setRequest(QBluetoothTransferRequest *request); + +protected: + QBluetoothTransferReplyPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QBluetoothTransferReply) + +}; + +Q_DECLARE_METATYPE(QBluetoothTransferReply *); + +QT_END_HEADER + +#endif // QBLUETOOTHTRANSFERREPLY_H diff --git a/src/bluetooth/qbluetoothtransferreply_bluez.cpp b/src/bluetooth/qbluetoothtransferreply_bluez.cpp new file mode 100644 index 00000000..07f1fb7c --- /dev/null +++ b/src/bluetooth/qbluetoothtransferreply_bluez.cpp @@ -0,0 +1,340 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qbluetoothtransferreply_bluez_p.h" +#include "qbluetoothaddress.h" + +#include "bluez/obex_client_p.h" +#include "bluez/obex_manager_p.h" +#include "bluez/obex_agent_p.h" +#include "bluez/obex_transfer_p.h" +#include "qbluetoothtransferreply.h" + +#include <QFuture> +#include <QFutureWatcher> +#include <QtConcurrentRun> + +static const QLatin1String agentPath("/qt/agent"); + + +QBluetoothTransferReplyBluez::QBluetoothTransferReplyBluez(QIODevice *input, QObject *parent) +: QBluetoothTransferReply(parent), tempfile(0), source(input), + m_running(false), m_finished(false), m_size(0), + m_error(QBluetoothTransferReply::NoError), m_errorStr(), m_transfer_path() +{ + client = new OrgOpenobexClientInterface(QLatin1String("org.openobex.client"), QLatin1String("/"), + QDBusConnection::sessionBus()); + +// manager = new OrgOpenobexManagerInterface(QLatin1String("org.openobex"), QLatin1String("/"), +// QDBusConnection::sessionBus()); + + qsrand(QTime::currentTime().msec()); + m_agent_path = agentPath; + m_agent_path.append(QString::fromLatin1("/%1").arg(qrand())); + + agent = new AgentAdaptor(this); + + bool res = QDBusConnection::sessionBus().registerObject(m_agent_path, this); +// res = QDBusConnection::sessionBus().registerService("org.qt.bt"); + if(!res) + qDebug() << "Failed Creating dbus objects"; + +#ifdef NOKIA_BT_SERVICES + connectToObexServerService(); +#endif +} + +/*! + Destroys the QBluetoothTransferReply object. +*/ +QBluetoothTransferReplyBluez::~QBluetoothTransferReplyBluez() +{ + QDBusConnection::sessionBus().unregisterObject(m_agent_path); + delete client; +} + +bool QBluetoothTransferReplyBluez::start() +{ + m_running = true; + +// qDebug() << "Got a:" << source->metaObject()->className(); + QFile *file = qobject_cast<QFile *>(source); + + if(!file){ + tempfile = new QTemporaryFile(this ); + tempfile->open(); +// qDebug() << "Not a QFile, making a copy" << tempfile->fileName(); + + QFutureWatcher<bool> *watcher = new QFutureWatcher<bool>(); + QObject::connect(watcher, SIGNAL(finished()), this, SLOT(copyDone())); + + QFuture<bool> results = QtConcurrent::run(QBluetoothTransferReplyBluez::copyToTempFile, tempfile, source); + watcher->setFuture(results); + } + else { + m_size = file->size(); + startOPP(file->fileName()); + } + return true; +} + +#ifdef NOKIA_BT_SERVICES +void QBluetoothTransferReplyBluez::connectToObexServerService() +{ + QServiceManager manager; + QServiceFilter filter("com.nokia.mt.obexserverservice.control"); +// filter.setServiceName("ObexServerServiceControl"); + + // find services complying with filter + QList<QServiceInterfaceDescriptor> foundServices; + foundServices = manager.findInterfaces(filter); + + if(foundServices.count()) { + m_obexService = manager.loadInterface(foundServices.at(0)); + } + if (m_obexService) { + qDebug() << "connected to service:" << m_obexService; + } else { + qDebug() << "failed to connect to Obex server service"; + } + + connect(m_obexService, SIGNAL(errorUnrecoverableIPCFault(QService::UnrecoverableIPCError)), SLOT(sfwIPCError(QService::UnrecoverableIPCError))); +} +#endif + +bool QBluetoothTransferReplyBluez::copyToTempFile(QIODevice *to, QIODevice *from) +{ + char *block = new char[4096]; + int size; + + while((size = from->read(block, 4096))) { + if(size != to->write(block, size)){ + return false; + } + } + + delete[] block; + return true; +} + +void QBluetoothTransferReplyBluez::copyDone() +{ + m_size = tempfile->size(); + startOPP(tempfile->fileName()); + QObject::sender()->deleteLater(); +} + +#ifdef NOKIA_BT_SERVICES +void QBluetoothTransferReplyBluez::sfwIPCError(QService::UnrecoverableIPCError error) +{ + qDebug() << "Connection to Obex server broken:" << error << ". Trying to reconnect..."; + m_obexService->deleteLater(); + QMetaObject::invokeMethod(this, "connectToObexServerService", Qt::QueuedConnection); +} +#endif + +void QBluetoothTransferReplyBluez::startOPP(QString filename) +{ + QVariantMap device; + QStringList files; + + device.insert(QString::fromLatin1("Destination"), address.toString()); + files << filename; + + QDBusObjectPath path(m_agent_path); + QDBusPendingReply<> sendReply = client->SendFiles(device, files, path); + + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(sendReply, this); + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(sendReturned(QDBusPendingCallWatcher*))); +} + +void QBluetoothTransferReplyBluez::sendReturned(QDBusPendingCallWatcher *watcher) +{ + + QDBusPendingReply<> sendReply = *watcher; + if(sendReply.isError()){ + qDebug() << "Failed to send file"<< sendReply.isError() << sendReply.error().message(); + m_finished = true; + m_running = false; + m_errorStr = sendReply.error().message(); + if(m_errorStr == QLatin1String("Could not open file for sending")) + m_error = QBluetoothTransferReply::FileNotFoundError; + else if(m_errorStr == QLatin1String("The transfer was canceled")) + m_error = QBluetoothTransferReply::UserCanceledTransferError; + else + m_error = QBluetoothTransferReply::UnknownError; + + // allow time for the developer to connect to the signal + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection, Q_ARG(QBluetoothTransferReply*, this)); + } +} + +QBluetoothTransferReply::TransferError QBluetoothTransferReplyBluez::error() const +{ + return m_error; +} + +QString QBluetoothTransferReplyBluez::errorString() const +{ + return m_errorStr; +} + +void QBluetoothTransferReplyBluez::Complete(const QDBusObjectPath &in0) +{ + Q_UNUSED(in0); + m_transfer_path.clear(); + m_finished = true; + m_running = false; + +#ifdef NOKIA_BT_SERVICES + if (m_obexService) + QMetaObject::invokeMethod(m_obexService, "setTransferFinished", Q_ARG(QString, in0.path()), Q_ARG(bool, true)); +#endif +} + +void QBluetoothTransferReplyBluez::Error(const QDBusObjectPath &in0, const QString &in1) +{ + Q_UNUSED(in0); + m_transfer_path.clear(); + m_finished = true; + m_running = false; + m_errorStr = in1; + if (in1 == QLatin1String("Could not open file for sending")) + m_error = QBluetoothTransferReply::FileNotFoundError; + else + m_error = QBluetoothTransferReply::UnknownError; + + emit finished(this); + +#ifdef NOKIA_BT_SERVICES + if (m_obexService) + QMetaObject::invokeMethod(m_obexService, "setTransferFinished", Q_ARG(QString, in0.path()), Q_ARG(bool, false)); +#endif +} + +void QBluetoothTransferReplyBluez::Progress(const QDBusObjectPath &in0, qulonglong in1) +{ + Q_UNUSED(in0); + emit uploadProgress(in1, m_size); + +#ifdef NOKIA_BT_SERVICES + if (m_obexService) + QMetaObject::invokeMethod(m_obexService, "setTransferProgress", Q_ARG(QString, in0.path()), Q_ARG(quint64, in1), Q_ARG(quint64, m_size)); +#endif +} + +void QBluetoothTransferReplyBluez::Release() +{ + if(m_errorStr.isEmpty()) + emit finished(this); +} + +QString QBluetoothTransferReplyBluez::Request(const QDBusObjectPath &in0) +{ + m_transfer_path = in0.path(); + +#ifdef NOKIA_BT_SERVICES + if (m_obexService) { + QFile *file = qobject_cast<QFile *>(source); + QMetaObject::invokeMethod(m_obexService, "outgoingFile", Q_ARG(QString, m_transfer_path), Q_ARG(QString, address.toString()), Q_ARG(QString, file->fileName()), Q_ARG(QString, QBluetoothTransferReply::attribute(QBluetoothTransferRequest::TypeAttribute).toString()), Q_ARG(quint64, m_size)); + QMetaObject::invokeMethod(m_obexService, "setTransferStarted", Q_ARG(QString, m_transfer_path)); + } +#endif + + return QString(); + +} + +/*! + Returns true if this reply has finished; otherwise returns false. +*/ +bool QBluetoothTransferReplyBluez::isFinished() const +{ + return m_finished; +} + +/*! + Returns true if this reply is running; otherwise returns false. +*/ +bool QBluetoothTransferReplyBluez::isRunning() const +{ + return m_running; +} + +void QBluetoothTransferReplyBluez::abort() +{ + if(!m_transfer_path.isEmpty()){ + OrgOpenobexTransferInterface *xfer = new OrgOpenobexTransferInterface(QLatin1String("org.openobex.client"), m_transfer_path, + QDBusConnection::sessionBus()); + QDBusPendingReply<> reply = xfer->Cancel(); + reply.waitForFinished(); + if(reply.isError()){ + qDebug() << "Failed to abort transfer" << reply.error(); + } + delete xfer; + +#ifdef NOKIA_BT_SERVICES + if (m_obexService) + QMetaObject::invokeMethod(m_obexService, "setTransferFinished", Q_ARG(QString, m_transfer_path), Q_ARG(bool, false)); +#endif + + } +} + +void QBluetoothTransferReplyBluez::setAddress(const QBluetoothAddress &destination) +{ + address = destination; +} + +qint64 QBluetoothTransferReplyBluez::readData(char*, qint64) +{ + return 0; +} + +qint64 QBluetoothTransferReplyBluez::writeData(const char*, qint64) +{ + return 0; +} + + +#include "moc_qbluetoothtransferreply_bluez_p.cpp" diff --git a/src/bluetooth/qbluetoothtransferreply_bluez_p.h b/src/bluetooth/qbluetoothtransferreply_bluez_p.h new file mode 100644 index 00000000..abc0b497 --- /dev/null +++ b/src/bluetooth/qbluetoothtransferreply_bluez_p.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHTRANSFERREPLY_BLUEZ_P_H +#define QBLUETOOTHTRANSFERREPLY_BLUEZ_P_H + +#include <QtCore/QIODevice> +#include <QtDBus/QtDBus> + +#include <qbluetoothtransferrequest.h> +#include <qbluetoothtransfermanager.h> + +#include "qbluetoothtransferreply.h" + +#ifdef NOKIA_BT_SERVICES +#include <QtServiceFramework/QServiceManager> +#endif + +QT_BEGIN_HEADER + +class OrgOpenobexClientInterface; +class OrgOpenobexManagerInterface; +class AgentAdaptor; + +class Q_CONNECTIVITY_EXPORT QBluetoothTransferReplyBluez : public QBluetoothTransferReply +{ + Q_OBJECT + +public: + explicit QBluetoothTransferReplyBluez(QIODevice *input, QObject *parent = 0); + ~QBluetoothTransferReplyBluez(); + + QVariant attribute(QBluetoothTransferRequest::Attribute code) const; + bool isFinished() const; + bool isRunning() const; + + bool start(); + + void startOPP(QString filename); + + void setAddress(const QBluetoothAddress &address); + + QBluetoothTransferReply::TransferError error() const; + QString errorString() const; + +protected: + qint64 readData(char*, qint64); + qint64 writeData(const char*, qint64); + +private: + OrgOpenobexClientInterface *client; + OrgOpenobexManagerInterface *manager; + AgentAdaptor *agent; + + QTemporaryFile *tempfile; + QIODevice *source; + + bool m_running; + bool m_finished; + + quint64 m_size; + + QBluetoothAddress address; + + QBluetoothTransferReply::TransferError m_error; + QString m_errorStr; + + QString m_agent_path; + + QString m_transfer_path; + +#ifdef NOKIA_BT_SERVICES + QObject *m_obexService; +#endif + + static bool copyToTempFile(QIODevice *to, QIODevice *from); + +private slots: + void copyDone(); + +#ifdef NOKIA_BT_SERVICES + void connectToObexServerService(); + void sfwIPCError(QService::UnrecoverableIPCError); +#endif + +public slots: + void abort(); + void Complete(const QDBusObjectPath &in0); + void Error(const QDBusObjectPath &in0, const QString &in1); + void Progress(const QDBusObjectPath &in0, qulonglong in1); + void Release(); + QString Request(const QDBusObjectPath &in0); + void sendReturned(QDBusPendingCallWatcher*); + +}; + +QT_END_HEADER + +#endif // QBLUETOOTHTRANSFERREPLY_H diff --git a/src/bluetooth/qbluetoothtransferreply_p.h b/src/bluetooth/qbluetoothtransferreply_p.h new file mode 100644 index 00000000..2e0058d4 --- /dev/null +++ b/src/bluetooth/qbluetoothtransferreply_p.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHTRANSFERREPLY_P_H +#define QBLUETOOTHTRANSFERREPLY_P_H + +#include "qbluetoothtransferreply.h" + +QT_BEGIN_HEADER + +class Q_CONNECTIVITY_EXPORT QBluetoothTransferReplyPrivate +{ +public: + QBluetoothTransferReplyPrivate(); + + QBluetoothTransferManager *m_manager; + QBluetoothTransferManager::Operation m_operation; + QMap<int, QVariant> m_attributes; + qint64 m_buffersize; + + QBluetoothTransferReply *q_ptr; + +}; + +QT_END_HEADER + +#endif // QBLUETOOTHTRANSFERREPLY_H diff --git a/src/bluetooth/qbluetoothtransferreply_symbian.cpp b/src/bluetooth/qbluetoothtransferreply_symbian.cpp new file mode 100644 index 00000000..e90c6017 --- /dev/null +++ b/src/bluetooth/qbluetoothtransferreply_symbian.cpp @@ -0,0 +1,315 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qbluetoothtransferreply_symbian_p.h" +#include "symbian/utils_symbian_p.h" +#include "qbluetoothservicediscoveryagent.h" +#include "qbluetoothserviceinfo.h" +#include "qbluetoothuuid.h" + +#include <QDebug> +#include <QFile> +#include <QFileInfo> +#include <QDir> + +QBluetoothTransferReplySymbian::QBluetoothTransferReplySymbian(QIODevice *input, + QBluetoothTransferManager::Operation operation, QObject *parent) + : QBluetoothTransferReply(parent) + , CActive(EPriorityStandard) + , m_source(input) + , m_running(false) + , m_finished(false) + , m_client(NULL) + , m_object(NULL) + , m_error(QBluetoothTransferReply::NoError) + , m_errorStr() + , m_timer(new QTimer(this)) +{ + setOperation(operation); + + //add this active object to scheduler + CActiveScheduler::Add(this); + connect(m_timer, SIGNAL(timeout()), this, SLOT(updateProgress())); + +} + +/*! + Destroys the QBluetoothTransferReply object. +*/ +QBluetoothTransferReplySymbian::~QBluetoothTransferReplySymbian() +{ + Cancel(); + + if (m_timer->isActive()) + m_timer->stop(); + + delete m_object; + m_object = NULL; + + delete m_client; + m_client = NULL; +} + +void QBluetoothTransferReplySymbian::setAddress(const QBluetoothAddress &address) +{ + m_address = address; +} + +void QBluetoothTransferReplySymbian::serviceDiscovered(const QBluetoothServiceInfo &info) +{ + m_port = info.serverChannel(); +} + +void QBluetoothTransferReplySymbian::updateProgress() +{ + if (m_object) { + qint64 sent = m_object->BytesSent(); + emit uploadProgress(sent, m_fileSize); + } +} + +void QBluetoothTransferReplySymbian::serviceDiscoveryFinished() +{ + QMetaObject::invokeMethod(this, "startTransfer", Qt::QueuedConnection); +} + +bool QBluetoothTransferReplySymbian::start() +{ + if (m_address.isNull()) + return false; + + m_running = true; + + m_discoveryAgent = new QBluetoothServiceDiscoveryAgent(m_address); + + connect(m_discoveryAgent, SIGNAL(serviceDiscovered(QBluetoothServiceInfo)), + this, SLOT(serviceDiscovered(QBluetoothServiceInfo))); + connect(m_discoveryAgent, SIGNAL(finished()), this, SLOT(serviceDiscoveryFinished())); + // Automatically delete agent when device discovery finishes. + connect(m_discoveryAgent, SIGNAL(finished()), this, SLOT(deleteLater())); + + m_discoveryAgent->setUuidFilter(QBluetoothUuid(QBluetoothUuid::ObexObjectPush)); + m_discoveryAgent->start(); + + return true; +} + +void QBluetoothTransferReplySymbian::startTransfer() +{ + TObexBluetoothProtocolInfo protocolInfo; + TBTDevAddr deviceAddress(m_address.toUInt64()); + + protocolInfo.iTransport.Copy(KBTSProtocol); + protocolInfo.iAddr.SetBTAddr(deviceAddress); + protocolInfo.iAddr.SetPort(m_port); // TODO: set port if needed + + if ( m_client ) { + delete m_client; + m_client = NULL; + } + + TRAPD( err, m_client = CObexClient::NewL(protocolInfo)); + if (err) { + qDebug() << "Error in" << __FUNCTION__ << err; + m_error = err == KErrNotFound ? HostNotFoundError: UnknownError; + return; + } + + m_state = EConnecting; + m_client->Connect( iStatus ); + + SetActive(); +} + +/*! + Returns true if this reply has finished; otherwise returns false. +*/ +bool QBluetoothTransferReplySymbian::isFinished() const +{ + return m_finished; +} + +/*! + Returns true if this reply is running; otherwise returns false. +*/ +bool QBluetoothTransferReplySymbian::isRunning() const +{ + return m_running; +} + +void QBluetoothTransferReplySymbian::abort() +{ + if (m_timer->isActive()) + m_timer->stop(); + m_state = EIdle; + m_running = false; + // Deleting obexclient is the only way to cancel active requests + delete m_client; + m_client = NULL; + + delete m_object; + m_object = NULL; +} + +QBluetoothTransferReply::TransferError QBluetoothTransferReplySymbian::error() const +{ + return m_error; +} + +QString QBluetoothTransferReplySymbian::errorString() const +{ + return m_errorStr; +} + +void QBluetoothTransferReplySymbian::DoCancel() +{ + m_running = false; + // Deleting obexclient is the only way to cancel active requests + if ( m_client ) { + delete m_client; + m_client = NULL; + m_state = EIdle; + } + if (m_timer->isActive()) + m_timer->stop(); + m_error = UserCanceledTransferError; +} + +void QBluetoothTransferReplySymbian::RunL() +{ + if (iStatus.Int() != KErrNone) { + abort(); + emit finished(this); + } + + switch ( m_state ) { + case EConnecting: { + m_state = ESending; + QFile *file = qobject_cast<QFile *>(m_source); + + QString filename; + if (file) { + QFileInfo info(*file); + m_fileSize = info.size(); + filename = QDir::toNativeSeparators(info.absoluteFilePath()); + } else { + if (copyToTempFile(m_tempfile, m_source)) { + QFileInfo info(*m_tempfile); + m_fileSize = info.size(); + filename = QDir::toNativeSeparators(info.absoluteFilePath()); + } else { + m_state = EDisconnecting; + disconnect(); + } + } + sendObject(filename); + break; + } + case ESending: { + m_state = EDisconnecting; + disconnect(); + break; + } + case EDisconnecting: { + m_state = EIdle; + m_finished = true; + m_running = false; + emit finished(this); + break; + } + case EIdle: + default: + break; + } + +} + +void QBluetoothTransferReplySymbian::sendObject(QString filename) +{ + delete m_object; + m_object = NULL; + TRAPD(err, m_object = CObexFileObject::NewL()); + if (!err) { + TPtrC16 str(reinterpret_cast<const TUint16*>(filename.utf16())); + TRAPD(error, m_object->InitFromFileL( str )); + if (!error) { + m_client->Put( *m_object, iStatus ); + m_timer->start(1000); + emit uploadProgress(0, m_fileSize); + SetActive(); + } else { + qDebug() << "Error in" << __FUNCTION__ << error; + m_error = error == KErrNotFound ? FileNotFoundError: UnknownError; + disconnect(); + emit finished(this); + } + } +} + +void QBluetoothTransferReplySymbian::disconnect() +{ + if ( m_state == EDisconnecting || m_error != NoError) { + if (m_timer->isActive()) + m_timer->stop(); + delete m_object; + m_object = NULL; + m_client->Disconnect( iStatus ); + SetActive(); + } +} + +bool QBluetoothTransferReplySymbian::copyToTempFile(QIODevice *to, QIODevice *from) +{ + char *block = new char[4096]; + + while (!from->atEnd()) { + int size = from->read(block, 4096); + if (size != to->write(block, size)) { + return false; + } + } + + delete[] block; + return true; +} + +#include "moc_qbluetoothtransferreply_symbian_p.cpp" diff --git a/src/bluetooth/qbluetoothtransferreply_symbian_p.h b/src/bluetooth/qbluetoothtransferreply_symbian_p.h new file mode 100644 index 00000000..002451ac --- /dev/null +++ b/src/bluetooth/qbluetoothtransferreply_symbian_p.h @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHTRANSFERREPLYSYMBIAN_H +#define QBLUETOOTHTRANSFERREPLYSYMBIAN_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qbluetoothtransferreply.h" +#include <e32base.h> +#include <obex.h> + +#include <QTemporaryFile> +#include <QIODevice> +#include <QTimer> + +QT_BEGIN_HEADER + +class QBluetoothServiceDiscoveryAgent; +class QBluetoothServiceInfo; + +_LIT( KBTSProtocol, "RFCOMM" ); // The Bluetooth transport layer + +class QBluetoothTransferReplySymbian : public QBluetoothTransferReply, public CActive +{ + Q_OBJECT + +public: + enum state + { + EIdle, + EConnecting, + ESending, + EDisconnecting + }; + + QBluetoothTransferReplySymbian(QIODevice *input, QBluetoothTransferManager::Operation, QObject *parent = 0); + ~QBluetoothTransferReplySymbian(); + + void abort(); + bool isFinished() const; + bool isRunning() const; + + bool start(); + + void setAddress(const QBluetoothAddress &address); + + QBluetoothTransferReply::TransferError error() const; + QString errorString() const; + +private: + void sendObject(QString filename); + void disconnect(); + + //From CActive + void DoCancel(); + void RunL(); + + static bool copyToTempFile(QIODevice *to, QIODevice *from); + +private slots: + void startTransfer(); + + void serviceDiscovered(const QBluetoothServiceInfo &info); + void serviceDiscoveryFinished(); + + void updateProgress(); + +private: + QIODevice *m_source; + QTemporaryFile *m_tempfile; + + QBluetoothAddress m_address; + QBluetoothServiceDiscoveryAgent* m_discoveryAgent; + + bool m_running; + bool m_finished; + + CObexClient* m_client; + CObexFileObject* m_object; + + QBluetoothTransferReply::TransferError m_error; + QString m_errorStr; + + state m_state; + qint64 m_fileSize; + int m_port; + + QTimer *m_timer; +}; + +QT_END_HEADER + +#endif // QBLUETOOTHTRANSFERREPLYPRIVATE_H diff --git a/src/bluetooth/qbluetoothtransferrequest.cpp b/src/bluetooth/qbluetoothtransferrequest.cpp new file mode 100644 index 00000000..e7245436 --- /dev/null +++ b/src/bluetooth/qbluetoothtransferrequest.cpp @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothtransferrequest.h" +#include "qbluetoothaddress.h" +#include "qbluetoothtransferrequest_p.h" + + +/*! + \class QBluetoothTransferRequest + \brief The QBluetoothTransferRequest class holds a request to be sent with + QBluetoothTransferManager. + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity + \since 5.0 + + QBluetoothTransferRequest is part of the Bluetooth Transfer API and is the class holding the + information necessary to initiate a transfer over Bluetooth. + + \sa QBluetoothTransferReply, QBluetoothTransferManager +*/ + +/*! + \enum QBluetoothTransferRequest::Attribute + + Attribute codes for QBluetoothTransferRequest and QBluetoothTransferReply. + + \value DescriptionAttribute A textural description of the object being transferred. May be + display in the UI of the remote device. + \value TimeAttribute Time attribute of the object being transferred. + \value TypeAttribute MIME type of the object being transferred. + \value LengthAttribute Length in bytes of the object being transferred. + \value NameAttribute Name of the object being transferred. May be displayed in the UI of + the remote device. +*/ + +/*! + Constructs a new Bluetooth transfer request to the device wit address \a address. +*/ +QBluetoothTransferRequest::QBluetoothTransferRequest(const QBluetoothAddress &address) +:d_ptr(new QBluetoothTransferRequestPrivate) +{ + Q_D(QBluetoothTransferRequest); + + d->m_address = address; +} + +/*! + Constructs a new Bluetooth transfer request that is a copy of \a other. +*/ +QBluetoothTransferRequest::QBluetoothTransferRequest(const QBluetoothTransferRequest &other) +:d_ptr(new QBluetoothTransferRequestPrivate) +{ + *this = other; +} + +/*! + Destorys the Bluetooth transfer request. +*/ +QBluetoothTransferRequest::~QBluetoothTransferRequest() +{ + delete d_ptr; +} + +/*! + Returns the attribute associated with code \a code. If the attribute has not been set, it + returns \a defaultValue. + + \sa setAttribute(), QBluetoothTransferRequest::Attribute +*/ +QVariant QBluetoothTransferRequest::attribute(Attribute code, const QVariant &defaultValue) const +{ + Q_D(const QBluetoothTransferRequest); + + if (d->m_parameters.contains((int)code)) { + return d->m_parameters.value((int)code); + } else { + return defaultValue; + } +} + +/*! + Sets the attribute associated with code \a code to be value \a value. If the attribute is + already set, the previous value is discarded. If \a value is an invalid QVariant, the attribute + is unset. + + \sa attribute(), QBluetoothTransferRequest::Attribute +*/ +void QBluetoothTransferRequest::setAttribute(Attribute code, const QVariant &value) +{ + Q_D(QBluetoothTransferRequest); + + d->m_parameters.insert((int)code, value); +} + +/*! + Returns the address associated with the Bluetooth transfer request. +*/ +QBluetoothAddress QBluetoothTransferRequest::address() const +{ + Q_D(const QBluetoothTransferRequest); + + return d->m_address; +} + + +/*! + Returns true if this object is not the same as \a other. + + \sa operator==() +*/ +bool QBluetoothTransferRequest::operator!=(const QBluetoothTransferRequest &other) const +{ + return !(*this == other); +} + +/*! + Creates a copy of \a other. +*/ +QBluetoothTransferRequest &QBluetoothTransferRequest::operator=(const QBluetoothTransferRequest &other) +{ + Q_D(QBluetoothTransferRequest); + + d->m_address = other.d_func()->m_address; + d->m_parameters = other.d_func()->m_parameters; + + return *this; +} + +/*! + Returns true if this object is the same as \a other. +*/ +bool QBluetoothTransferRequest::operator==(const QBluetoothTransferRequest &other) const +{ + Q_D(const QBluetoothTransferRequest); + if (d->m_address == other.d_func()->m_address && d->m_parameters == other.d_func()->m_parameters) { + return true; + } + return false; +} + +QBluetoothTransferRequestPrivate::QBluetoothTransferRequestPrivate() +{ +} + diff --git a/src/bluetooth/qbluetoothtransferrequest.h b/src/bluetooth/qbluetoothtransferrequest.h new file mode 100644 index 00000000..43322b22 --- /dev/null +++ b/src/bluetooth/qbluetoothtransferrequest.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHTRANSFERREQUEST_H +#define QBLUETOOTHTRANSFERREQUEST_H + +#include "../qtconnectivityglobal.h" + +#include <QtCore/QtGlobal> +#include <QtCore/QVariant> + +QT_BEGIN_HEADER + +class QBluetoothAddress; +class QBluetoothTransferRequestPrivate; + +class Q_CONNECTIVITY_EXPORT QBluetoothTransferRequest +{ +public: + enum Attribute { + DescriptionAttribute, + TimeAttribute, + TypeAttribute, + LengthAttribute, + NameAttribute + }; + + QBluetoothTransferRequest(const QBluetoothAddress &address); + QBluetoothTransferRequest(const QBluetoothTransferRequest &other); + ~QBluetoothTransferRequest(); + + QVariant attribute(Attribute code, const QVariant &defaultValue = QVariant()) const; + void setAttribute(Attribute code, const QVariant &value); + + QBluetoothAddress address() const; + + bool operator!=(const QBluetoothTransferRequest &other) const; + QBluetoothTransferRequest &operator=(const QBluetoothTransferRequest &other); + bool operator==(const QBluetoothTransferRequest &other) const; + +protected: + QBluetoothTransferRequestPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QBluetoothTransferRequest) + +}; + +QT_END_HEADER + +#endif // QBLUETOOTHTRANSFERREQUEST_H diff --git a/src/bluetooth/qbluetoothtransferrequest_p.h b/src/bluetooth/qbluetoothtransferrequest_p.h new file mode 100644 index 00000000..decf939c --- /dev/null +++ b/src/bluetooth/qbluetoothtransferrequest_p.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHTRANSFERREQUESTPRIVATE_H +#define QBLUETOOTHTRANSFERREQUESTPRIVATE_H + +#include "../qtconnectivityglobal.h" +#include "qbluetoothtransferrequest.h" + +QT_BEGIN_HEADER + +class QBluetoothAddress; + +class QBluetoothTransferRequestPrivate +{ +public: + QBluetoothTransferRequestPrivate(); + + QBluetoothAddress m_address; + QMap<int, QVariant> m_parameters; +}; + +QT_END_HEADER + +#endif // QBLUETOOTHTRANSFERREQUESTPRIVATE_H diff --git a/src/bluetooth/qbluetoothuuid.cpp b/src/bluetooth/qbluetoothuuid.cpp new file mode 100644 index 00000000..c4b57c5b --- /dev/null +++ b/src/bluetooth/qbluetoothuuid.cpp @@ -0,0 +1,358 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbluetoothuuid.h" + +#include <QStringList> + +#include <QDebug> + +#include <QtEndian> + +//#include <arpa/inet.h> +//#include <netinet/in.h> +#include <string.h> + +// Bluetooth base UUID 00000000-0000-1000-8000-00805F9B34FB +// TODO: make more efficient +Q_GLOBAL_STATIC_WITH_ARGS(QUuid, baseUuid, ("{00000000-0000-1000-8000-00805F9B34FB}")) + +/*! + \class QBluetoothUuid + \brief The QBluetoothUuid class provides a Bluetooth UUID. + \since 5.0 + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity +*/ + +/*! + \enum QBluetoothUuid::ProtocolUuid + + This enum is a convienience type for Bluetooth protocol UUIDs. Values of this type will be + implicitly converted into a QBluetoothUuid when necessary. + + \value Sdp SDP protocol UUID. + \value Udp UDP protocol UUID. + \value Rfcomm RFCOMM protocol UUID. + \value Tcp TCP protocol UUID. + \value TcsBin Telephony Control Specification UUID. + \value TcsAt Telephony Control Specification AT UUID. + \value Obex OBEX protocol UUID. + \value Ip IP protocol UUID. + \value Ftp FTP protocol UUID. + \value Http HTTP protocol UUID. + \value Wsp WSP UUID + \value Bnep Bluetooth Network Encapsulation Protocol UUID + \value Upnp Extended Service Discovery Profile UUID + \value Hidp Human Interface Device Profile UUID + \value HardcopyControlChannel Hardcopy Cable Replacement Profile UUID + \value HardcopyDataChannel Hardcopy Cable Replacement Profile UUID + \value HardcopyNotification Hardcopy Cable Replacement Profile UUID + \value Avctp Audio/Video Control Transport Protocol UUID + \value Avdtp Audio/Video Distribution Transport Protocol UUID + \value Cmtp Common ISDN Access Profile + \value UdiCPlain UDI protocol UUID + \value McapControlChannel Multi-Channel Adaptation Protocol UUID + \value McapDataChannel Multi-Channel Adaptation Protocol UUID + \value L2cap L2CAP protocol UUID. +*/ + +/*! + \enum QBluetoothUuid::ServiceClassUuid + + This enum is a convienience type for Bluetooth service class UUIDs. Values of this type will be + implicitly converted into a QBluetoothUuid when necessary. + + \value PublicBrowseGroup Public browse group service class. Services which have the public + browse group in their + \l {QBluetoothServiceInfo::BrowseGroupList}{browse group list} are + discoverable by remote devices. + \value ObexObjectPush OBEX object push service UUID. + \value ServiceDiscoveryServer + \value BrowseGroupDescriptor Browser group descriptor + \value SerialPort Serial Port Profile UUID + \value LANAccessUsingPPP LAN Access Profile UUID + \value DialupNetworking Dial-up Networking Profile UUID + \value IrMCSync Synchronization Profile UUID + \value OBEXFileTransfer File Transfer Profile (FTP) UUID + \value IrMCSyncCommand Synchronization Profile UUID + \value Headset Headset Profile (HSP) UUID + \value AudioSource Advanced Audio Distribution Profile (A2DP) UUID + \value AudioSink Advanced Audio Distribution Profile (A2DP) UUID + \value AV_RemoteControlTarget Audio/Video Remote Control Profile (AVRCP) UUID + \value AdvancedAudioDistribution Advanced Audio Distribution Profile (A2DP) UUID + \value AV_RemoteControl Audio/Video Remote Control Profile (AVRCP) UUID + \value AV_RemoteControlController Audio/Video Remote Control Profile UUID + \value HeadsetAG Headset Profile (HSP) UUID + \value PANU Personal Area Networking Profile (PAN) UUID + \value NAP Personal Area Networking Profile (PAN) UUID + \value GN Personal Area Networking Profile (PAN) UUID + \value DirectPrinting Basic Printing Profile (BPP) UUID + \value ReferencePrinting Related to Basic Printing Profile (BPP) UUID + \value ImagingResponder Basic Imaging Profile (BIP) UUID + \value ImagingResponder Basic Imaging Profile (BIP) UUID + \value ImagingAutomaticArchive Basic Imaging Profile (BIP) UUID + \value Handsfree Hands-Free Profile (HFP) Service Class Identifier and Profile Identifier + \value HandsfreeAudioGateway Hands-free Profile (HFP) UUID + \value DirectPrintingReferenceObjectsService Basic Printing Profile (BPP) UUID + \value ReflectedUI Basic Printing Profile (BPP) UUID + \value BasicPrinting Basic Printing Profile (BPP) UUID + \value PrintingStatus Basic Printing Profile (BPP) UUID + \value HumanInterfaceDeviceService Human Interface Device (HID) UUID + \value HardcopyCableReplacement Hardcopy Cable Replacement Profile (HCRP) + \value HCRPrint Hardcopy Cable Replacement Profile (HCRP) + \value HCRScan Hardcopy Cable Replacement Profile (HCRP) + \value SIMAccess SIM Access Profile (SAP) UUID + \value PhonebookAccessPCE Phonebook Access Profile (PBAP) UUID + \value PhonebookAccessPSE Phonebook Access Profile (PBAP) UUID + \value PhonebookAccess Phonebook Access Profile (PBAP) + \value HeadsetHS Headset Profile (HSP) UUID + \value MessageAccessServer Message Access Profile (MAP) UUID + \value MessageNotificationServer Message Access Profile (MAP) UUID + \value MessageAccessProfile Message Access Profile (MAP) UUID + \value PnPInformation Device Identification (DID) UUID + \value GenericNetworking Generic networking + \value GenericFileTransfer Generic file transfer + \value GenericAudio Generic audio + \value GenericTelephony Generic telephone + \value VideoSource Video Distribution Profile (VDP) + \value VideoSink Video Distribution Profile (VDP) + \value VideoDistribution Video Distribution Profile (VDP) + \value HDP Health Device Profile + \value HDPSource Health Device Profile + \value HDPSink Health Device Profile +*/ + +/*! + Constructs a new null Bluetooth UUID. +*/ +QBluetoothUuid::QBluetoothUuid() +{ +} + +/*! + Constructs a new Bluetooth UUID from the protocol UUID \a uuid. +*/ +QBluetoothUuid::QBluetoothUuid(ProtocolUuid uuid) +: QUuid(uuid, baseUuid()->data2, + baseUuid()->data3, baseUuid()->data4[0], baseUuid()->data4[1], + baseUuid()->data4[2], baseUuid()->data4[3], baseUuid()->data4[4], baseUuid()->data4[5], + baseUuid()->data4[6], baseUuid()->data4[7]) +{ +} + +/*! + Constructs a new Bluetooth UUID from the service class UUID \a uuid. +*/ +QBluetoothUuid::QBluetoothUuid(ServiceClassUuid uuid) +: QUuid(uuid, baseUuid()->data2, baseUuid()->data3, baseUuid()->data4[0], baseUuid()->data4[1], + baseUuid()->data4[2], baseUuid()->data4[3], baseUuid()->data4[4], baseUuid()->data4[5], + baseUuid()->data4[6], baseUuid()->data4[7]) +{ +} + +/*! + Constructs a new Bluetooth UUID from the 16 bit UUID \a uuid. +*/ +QBluetoothUuid::QBluetoothUuid(quint16 uuid) +: QUuid(uuid, baseUuid()->data2, baseUuid()->data3, baseUuid()->data4[0], baseUuid()->data4[1], + baseUuid()->data4[2], baseUuid()->data4[3], baseUuid()->data4[4], baseUuid()->data4[5], + baseUuid()->data4[6], baseUuid()->data4[7]) +{ +} + +/*! + Constructs a new Bluetooth UUID from the 32 bit UUID \a uuid. +*/ +QBluetoothUuid::QBluetoothUuid(quint32 uuid) +: QUuid(uuid, baseUuid()->data2, baseUuid()->data3, baseUuid()->data4[0], baseUuid()->data4[1], + baseUuid()->data4[2], baseUuid()->data4[3], baseUuid()->data4[4], baseUuid()->data4[5], + baseUuid()->data4[6], baseUuid()->data4[7]) +{ +} + +/*! + Constructs a new Bluetooth UUID from the 128 bit UUID \a uuid. +*/ +QBluetoothUuid::QBluetoothUuid(quint128 uuid) +{ + // TODO: look at the memcpy(), should not be needed + quint32 tmp32; + memcpy(&tmp32, &uuid.data[0], 4); + data1 = qFromBigEndian<quint32>(tmp32); + + quint16 tmp16; + memcpy(&tmp16, &uuid.data[4], 2); + data2 = qFromBigEndian<quint16>(tmp16); + + memcpy(&tmp16, &uuid.data[6], 2); + data3 = qFromBigEndian<quint16>(tmp16); + + memcpy(data4, &uuid.data[8], 8); +} + +/*! + Constructs a new Bluetooth UUID from the string \a uuid. + + The string must be in the form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX. +*/ +QBluetoothUuid::QBluetoothUuid(const QString &uuid) +: QUuid(uuid) +{ +} + +/*! + Constructs a new Bluetooth UUID that is a copy of \a uuid. +*/ +QBluetoothUuid::QBluetoothUuid(const QBluetoothUuid &uuid) +: QUuid(uuid) +{ +} + +/*! + Constructs a new Bluetooth UUID that is a copy of \a uuid. +*/ +QBluetoothUuid::QBluetoothUuid(const QUuid &uuid) +: QUuid(uuid) +{ +} + +/*! + Destroys the Bluetooth UUID. +*/ +QBluetoothUuid::~QBluetoothUuid() +{ +} + +/*! + Returns the minimum size in bytes that this UUID can be represented in. For non-null UUIDs 2, + 4 or 16 is returned. 0 is returned for null UUIDs. + + \sa isNull(), toUInt16(), toUInt32(), toUInt128() +*/ +int QBluetoothUuid::minimumSize() const +{ + if (data2 == baseUuid()->data2 && data3 == baseUuid()->data3 && + memcmp(data4, baseUuid()->data4, 8) == 0) { + // 16 or 32 bit Bluetooth UUID + if (data1 & 0xFFFF0000) + return 4; + else + return 2; + } + + if (isNull()) + return 0; + + return 16; +} + +/*! + Returns the 16 bit representation of this UUID. If \a ok is passed it is set to true if the + conversion is possible otherwise it is set to false. The return value is undefined if \a ok is + set to false. +*/ +quint16 QBluetoothUuid::toUInt16(bool *ok) const +{ + if (data1 & 0xFFFF0000 || data2 != baseUuid()->data2 || data3 != baseUuid()->data3 || + memcmp(data4, baseUuid()->data4, 8) != 0) { + // not convertable to 16 bit Bluetooth UUID. + if (ok) + *ok = false; + return 0; + } + + if (ok) + *ok = true; + + return data1; +} + +/*! + Returns the 32 bit representation of this UUID. If \a ok is passed it is set to true if the + conversion is possible otherwise it is set to false. The return value is undefined if \a ok is + set to false. +*/ +quint32 QBluetoothUuid::toUInt32(bool *ok) const +{ + if (data2 != baseUuid()->data2 || data3 != baseUuid()->data3 || + memcmp(data4, baseUuid()->data4, 8) != 0) { + // not convertable to 32 bit Bluetooth UUID. + if (ok) + *ok = false; + return 0; + } + + if (ok) + *ok = true; + + return data1; +} + +/*! + Returns the 128 bit representation of this UUID. +*/ +quint128 QBluetoothUuid::toUInt128() const +{ + quint128 uuid; + + quint32 tmp32 = qToBigEndian<quint32>(data1); + memcpy(&uuid.data[0], &tmp32, 4); + + quint16 tmp16 = qToBigEndian<quint16>(data2); + memcpy(&uuid.data[4], &tmp16, 2); + + tmp16 = qToBigEndian<quint16>(data3); + memcpy(&uuid.data[6], &tmp16, 2); + + memcpy(&uuid.data[8], data4, 8); + + return uuid; +} + +/*! + Returns true if \a other is equal to this Bluetooth UUID; otherwise returns false. +*/ +bool QBluetoothUuid::operator==(const QBluetoothUuid &other) const +{ + return QUuid::operator==(other); +} diff --git a/src/bluetooth/qbluetoothuuid.h b/src/bluetooth/qbluetoothuuid.h new file mode 100644 index 00000000..09e0db65 --- /dev/null +++ b/src/bluetooth/qbluetoothuuid.h @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QBLUETOOTHUUID_H +#define QBLUETOOTHUUID_H + +#include "../qtconnectivityglobal.h" + +#include <QtCore/QtGlobal> +#include <QtCore/QMetaType> +#include <QtCore/QUuid> + +#include <QtCore/QDebug> + +QT_BEGIN_HEADER + +struct quint128 +{ + quint8 data[16]; +}; + +class Q_CONNECTIVITY_EXPORT QBluetoothUuid : public QUuid +{ +public: + enum ProtocolUuid { + Sdp = 0x0001, + Udp = 0x0002, + Rfcomm = 0x0003, + Tcp = 0x0004, + TcsBin = 0x0005, + TcsAt = 0x0006, + Obex = 0x0008, + Ip = 0x0009, + Ftp = 0x000A, + Http = 0x000C, + Wsp = 0x000E, + Bnep = 0x000F, + Upnp = 0x0010, + Hidp = 0x0011, + HardcopyControlChannel = 0x0012, + HardcopyDataChannel = 0x0014, + HardcopyNotification = 0x0016, + Avctp = 0x0017, + Avdtp = 0x0019, + Cmtp = 0x001B, + UdiCPlain = 0x001D, + McapControlChannel = 0x001E, + McapDataChannel = 0x001F, + L2cap = 0x0100, + }; + + enum ServiceClassUuid { + ServiceDiscoveryServer = 0x1000, + BrowseGroupDescriptor = 0x1001, + PublicBrowseGroup = 0x1002, + SerialPort = 0x1101, + LANAccessUsingPPP = 0x1102, + DialupNetworking = 0x1103, + IrMCSync = 0x1104, + ObexObjectPush = 0x1105, + OBEXFileTransfer = 0x1106, + IrMCSyncCommand = 0x1107, + Headset = 0x1108, + AudioSource = 0x110a, + AudioSink = 0x110b, + AV_RemoteControlTarget = 0x110c, + AdvancedAudioDistribution = 0x110d, + AV_RemoteControl = 0x110e, + AV_RemoteControlController = 0x110f, + HeadsetAG = 0x1112, + PANU = 0x1115, + NAP = 0x1116, + GN = 0x1117, + DirectPrinting = 0x1118, + ReferencePrinting = 0x1119, + ImagingResponder = 0x111b, + ImagingAutomaticArchive = 0x111c, + Handsfree = 0x111d, + HandsfreeAudioGateway = 0x111f, + DirectPrintingReferenceObjectsService = 0x1120, + ReflectedUI = 0x1121, + BasicPrinting = 0x1122, + PrintingStatus = 0x1123, + HumanInterfaceDeviceService = 0x1124, + HardcopyCableReplacement = 0x1125, + HCRPrint = 0x1126, + HCRScan = 0x1127, + SIMAccess = 0x112d, + PhonebookAccessPCE = 0x112e, + PhonebookAccessPSE = 0x112f, + PhonebookAccess = 0x1130, + HeadsetHS = 0x1131, + MessageAccessServer = 0x1132, + MessageNotificationServer = 0x1133, + MessageAccessProfile = 0x1134, + PnPInformation = 0x1135, + GenericNetworking = 0x1201, + GenericFileTransfer = 0x1202, + GenericAudio = 0x1203, + GenericTelephony = 0x1204, + VideoSource = 0x1303, + VideoSink = 0x1304, + VideoDistribution = 0x1305, + HDP = 0x1400, + HDPSource = 0x1401, + HDPSink = 0x1402 + }; + + QBluetoothUuid(); + QBluetoothUuid(ProtocolUuid uuid); + QBluetoothUuid(ServiceClassUuid uuid); + explicit QBluetoothUuid(quint16 uuid); + explicit QBluetoothUuid(quint32 uuid); + explicit QBluetoothUuid(quint128 uuid); + explicit QBluetoothUuid(const QString &uuid); + QBluetoothUuid(const QBluetoothUuid &uuid); + QBluetoothUuid(const QUuid &uuid); + ~QBluetoothUuid(); + + bool operator==(const QBluetoothUuid &other) const; + + int minimumSize() const; + + quint16 toUInt16(bool *ok = 0) const; + quint32 toUInt32(bool *ok = 0) const; + quint128 toUInt128() const; +}; + +inline QDebug operator<<(QDebug debug, const QBluetoothUuid &uuid) +{ + debug << uuid.toString(); + return debug; +} + +Q_DECLARE_METATYPE(QBluetoothUuid) + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/ql2capserver.cpp b/src/bluetooth/ql2capserver.cpp new file mode 100644 index 00000000..97676c2e --- /dev/null +++ b/src/bluetooth/ql2capserver.cpp @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "ql2capserver.h" +#include "ql2capserver_p.h" +#include "qbluetoothsocket.h" + +/*! + \class QL2capServer + \brief The QL2capServer class provides an L2CAP server. + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity + \since 5.0 + + QL2capServer is used to implement Bluetooth services over L2CAP. + + Start listening for incoming connections with listen(). The newConnection() signal is emitted + when a new connection is established. Call nextPendingConnection() to get a QBluetoothSocket + for the new connection. + + to enable other devices to find your service create a QBluetoothServiceInfo with the applicable + attributes for your service and register it with QBluetoothServiceInfo::registerService(). Call + serverPort() to get the L2CAP port number that is being used. + + \sa QBluetoothServiceInfo, QBluetoothSocket +*/ + +/*! + \fn void QL2capServer::newConnection() + + This signal is emitted when a new connection is available. + + The connected slot should call nextPendingConnection() to get a QBluetoothSocket object to send + and receive data over the connection. + + \sa nextPendingConnection(), hasPendingConnections() +*/ + +/*! + \fn void QL2capServer::close() + + Closes and resets the listening socket. +*/ + +/*! + \fn bool QL2capServer::listen(const QBluetoothAddress &address, quint16 port) + + Start listening for incoming connections to \a address on \a port. + + Returns true if the operation succeeded and the L2CAP server is listening for incoming + connections; otherwise returns false. + + \sa isListening(), newConnection() +*/ + +/*! + \fn void QL2capServer::setMaxPendingConnections(int numConnections) + + Sets the maximum number of pending connections to \a numConnections. + + \sa maxPendingConnections() +*/ + +/*! + \fn bool QL2capServer::hasPendingConnections() const + + Returns true if a connection is pending; otherwise returns false. +*/ + +/*! + \fn QBluetoothSocket *QL2capServer::nextPendingConnection() + + Returns a pointer to a QBluetoothSocket for the next pending connection. It is the callers + responsibility to delete the pointer. +*/ + +/*! + \fn QBluetoothAddress QL2capServer::serverAddress() const + + Returns the server address. +*/ + +/*! + \fn quint16 QL2capServer::serverPort() const + + Returns the server's port number. +*/ + +/*! + Constructs an L2CAP server with \a parent. +*/ +QL2capServer::QL2capServer(QObject *parent) +: QObject(parent), d_ptr(new QL2capServerPrivate) +{ + d_ptr->q_ptr = this; +} + +/*! + Destorys the L2CAP server. +*/ +QL2capServer::~QL2capServer() +{ + delete d_ptr; +} + +/*! + Returns true if the L2CAP server is listening for incoming connections; otherwise returns + false. +*/ +bool QL2capServer::isListening() const +{ + Q_D(const QL2capServer); + + return d->socket->state() == QBluetoothSocket::ListeningState; +} + +/*! + Returns the maximum number of pending connections. + + \sa setMaxPendingConnections() +*/ +int QL2capServer::maxPendingConnections() const +{ + Q_D(const QL2capServer); + + return d->maxPendingConnections; +} + +/*! + \fn void QL2capServer::setSecurityFlags(QBluetooth::SecurityFlags security) + Sets the Bluetooth security flags to \a security. This function must be called prior to calling + listen(). +*/ + +/*! + \fn QBluetooth::SecurityFlags QL2capServer::securityFlags() const + + Returns the Bluetooth security flags. +*/ + +#include "moc_ql2capserver.cpp" diff --git a/src/bluetooth/ql2capserver.h b/src/bluetooth/ql2capserver.h new file mode 100644 index 00000000..23155ef3 --- /dev/null +++ b/src/bluetooth/ql2capserver.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QL2CAPSERVER_H +#define QL2CAPSERVER_H + +#include "../qtconnectivityglobal.h" + +#include <QObject> + +#include <qbluetoothaddress.h> +#include <qbluetooth.h> +#include <qbluetoothsocket.h> + +QT_BEGIN_HEADER + +class QL2capServerPrivate; +class QBluetoothSocket; + +class Q_CONNECTIVITY_EXPORT QL2capServer : public QObject +{ + Q_OBJECT + +public: + QL2capServer(QObject *parent = 0); + ~QL2capServer(); + + void close(); + + bool listen(const QBluetoothAddress &address = QBluetoothAddress(), quint16 port = 0); + bool isListening() const; + + void setMaxPendingConnections(int numConnections); + int maxPendingConnections() const; + + bool hasPendingConnections() const; + QBluetoothSocket *nextPendingConnection(); + + QBluetoothAddress serverAddress() const; + quint16 serverPort() const; + + void setSecurityFlags(QBluetooth::SecurityFlags security); + QBluetooth::SecurityFlags securityFlags() const; + +signals: + void newConnection(); + +protected: + QL2capServerPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QL2capServer) + +#ifdef QT_SYMBIAN_BLUETOOTH + Q_PRIVATE_SLOT(d_func(), void _q_connected()) + Q_PRIVATE_SLOT(d_func(), void _q_socketError(QBluetoothSocket::SocketError err)) + Q_PRIVATE_SLOT(d_func(), void _q_disconnected()) +#endif //QT_SYMBIAN_BLUETOOTH + +#ifdef QT_BLUEZ_BLUETOOTH + Q_PRIVATE_SLOT(d_func(), void _q_newConnection()) +#endif + +}; + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/ql2capserver_bluez.cpp b/src/bluetooth/ql2capserver_bluez.cpp new file mode 100644 index 00000000..7f02c521 --- /dev/null +++ b/src/bluetooth/ql2capserver_bluez.cpp @@ -0,0 +1,245 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "ql2capserver.h" +#include "ql2capserver_p.h" +#include "qbluetoothsocket.h" + +#include <QtCore/QSocketNotifier> + +#include <QtCore/QDebug> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/l2cap.h> + +#include <errno.h> + +static inline void convertAddress(quint64 from, quint8 (&to)[6]) +{ + to[0] = (from >> 0) & 0xff; + to[1] = (from >> 8) & 0xff; + to[2] = (from >> 16) & 0xff; + to[3] = (from >> 24) & 0xff; + to[4] = (from >> 32) & 0xff; + to[5] = (from >> 40) & 0xff; +} + +QL2capServerPrivate::QL2capServerPrivate() +: pending(false), maxPendingConnections(1), socketNotifier(0) +{ + socket = new QBluetoothSocket(QBluetoothSocket::L2capSocket); +} + +QL2capServerPrivate::~QL2capServerPrivate() +{ + qDebug() << "Deleted"; + delete socketNotifier; + + delete socket; +} + +void QL2capServerPrivate::_q_newConnection() +{ + // disable socket notifier until application calls nextPendingConnection(). + socketNotifier->setEnabled(false); + + emit q_ptr->newConnection(); +} + +void QL2capServer::close() +{ + Q_D(QL2capServer); + + d->socket->close(); +} + +bool QL2capServer::listen(const QBluetoothAddress &address, quint16 port) +{ + Q_D(QL2capServer); + + int sock = d->socket->socketDescriptor(); + if (sock < 0) + return false; + + sockaddr_l2 addr; + + memset(&addr, 0, sizeof(sockaddr_l2)); + addr.l2_family = AF_BLUETOOTH; + addr.l2_psm = port; + + if (!address.isNull()) + convertAddress(address.toUInt64(), addr.l2_bdaddr.b); + else + convertAddress(Q_UINT64_C(0), addr.l2_bdaddr.b); + + if (::bind(sock, reinterpret_cast<sockaddr *>(&addr), sizeof(sockaddr_l2)) < 0) + return false; + + if (::listen(sock, d->maxPendingConnections) < 0) + return false; + + d->socket->setSocketState(QBluetoothSocket::ListeningState); + + delete d->socketNotifier; + + d->socketNotifier = new QSocketNotifier(d->socket->socketDescriptor(), + QSocketNotifier::Read); + connect(d->socketNotifier, SIGNAL(activated(int)), this, SLOT(_q_newConnection())); + + return true; +} + +void QL2capServer::setMaxPendingConnections(int numConnections) +{ + Q_D(QL2capServer); + + if (d->socket->state() == QBluetoothSocket::UnconnectedState) + d->maxPendingConnections = numConnections; +} + +bool QL2capServer::hasPendingConnections() const +{ + Q_D(const QL2capServer); + + if (!d || !d->socketNotifier) + return false; + + // if the socket notifier is disable there is a pending connection waiting for us to accept. + return !d->socketNotifier->isEnabled(); +} + +QBluetoothSocket *QL2capServer::nextPendingConnection() +{ + Q_D(QL2capServer); + + if (!hasPendingConnections()) + return 0; + + sockaddr_l2 addr; + socklen_t length = sizeof(sockaddr_l2); + + int pending = ::accept(d->socket->socketDescriptor(), + reinterpret_cast<sockaddr *>(&addr), &length); + if (pending >= 0) { + QBluetoothSocket *newSocket = new QBluetoothSocket; + newSocket->setSocketDescriptor(pending, QBluetoothSocket::L2capSocket); + + d->socketNotifier->setEnabled(true); + + return newSocket; + } else { +// qDebug() << "Hmm, could have sworn there was a connection waiting to be accepted!" << errno; + d->socketNotifier->setEnabled(true); + } + + return 0; +} + +QBluetoothAddress QL2capServer::serverAddress() const +{ + Q_D(const QL2capServer); + + return d->socket->localAddress(); +} + +quint16 QL2capServer::serverPort() const +{ + Q_D(const QL2capServer); + + return d->socket->localPort(); +} + +void QL2capServer::setSecurityFlags(QBluetooth::SecurityFlags security) +{ + Q_D(QL2capServer); + + int lm = 0; + if(security == QBluetooth::NoSecurity){ + lm = 0; + } + if(security.testFlag(QBluetooth::Authorization)){ + lm |= L2CAP_LM_AUTH; + } + if(security.testFlag(QBluetooth::Authentication)){ + lm |= L2CAP_LM_TRUSTED; + } + if(security.testFlag(QBluetooth::Encryption)){ + lm |= L2CAP_LM_ENCRYPT; + } + if(security.testFlag(QBluetooth::Secure)){ + lm |= L2CAP_LM_SECURE; + } + + if(setsockopt(d->socket->socketDescriptor(), SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0){ + qWarning() << "Failed to set socket option, closing socket for safety" << errno; + qWarning() << "Error: " << strerror(errno); + d->socket->close(); + } +} + +QBluetooth::SecurityFlags QL2capServer::securityFlags() const +{ + Q_D(const QL2capServer); + + int lm = 0; + int len = sizeof(lm); + int security = QBluetooth::NoSecurity; + + if(getsockopt(d->socket->socketDescriptor(), SOL_L2CAP, L2CAP_LM, &lm, (socklen_t *)&len) < 0) { + qWarning() << "Failed to get security flags" << strerror(errno); + return QBluetooth::NoSecurity; + } + + if(lm & L2CAP_LM_SECURE) + security |= QBluetooth::Secure; + + if(lm & L2CAP_LM_ENCRYPT) + security |= QBluetooth::Encryption; + + if(lm & L2CAP_LM_TRUSTED) + security |= QBluetooth::Authentication; + + if(lm & L2CAP_LM_AUTH) + security |= QBluetooth::Authorization; + + return static_cast<QBluetooth::SecurityFlags>(security); +} + diff --git a/src/bluetooth/ql2capserver_p.cpp b/src/bluetooth/ql2capserver_p.cpp new file mode 100644 index 00000000..0a284ced --- /dev/null +++ b/src/bluetooth/ql2capserver_p.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "ql2capserver.h" +#include "ql2capserver_p.h" +#include "qbluetoothsocket.h" + +QL2capServerPrivate::QL2capServerPrivate() +{ +} + +QL2capServerPrivate::~QL2capServerPrivate() +{ +} + +void QL2capServer::close() +{ +} + +bool QL2capServer::listen(const QBluetoothAddress &address, quint16 port) +{ + Q_UNUSED(address); + Q_UNUSED(port); + + return false; +} + +void QL2capServer::setMaxPendingConnections(int numConnections) +{ + Q_UNUSED(numConnections); +} + +bool QL2capServer::hasPendingConnections() const +{ + return false; +} + +QBluetoothSocket *QL2capServer::nextPendingConnection() +{ + return 0; +} + +QBluetoothAddress QL2capServer::serverAddress() const +{ + return QBluetoothAddress(); +} + +quint16 QL2capServer::serverPort() const +{ + return 0; +} + +void QL2capServer::setSecurityFlags(QBluetooth::SecurityFlags security) +{ +} + +QBluetooth::SecurityFlags QL2capServer::securityFlags() const +{ + return QBluetooth::NoSecurity; +} + + + +#ifdef QT_BLUEZ_BLUETOOTH +void QL2capServerPrivate::_q_newConnection() +{ +} +#endif diff --git a/src/bluetooth/ql2capserver_p.h b/src/bluetooth/ql2capserver_p.h new file mode 100644 index 00000000..b8f056d8 --- /dev/null +++ b/src/bluetooth/ql2capserver_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QL2CAPSERVER_P_H +#define QL2CAPSERVER_P_H + +#include "../qtconnectivityglobal.h" +#include <qbluetoothsocket.h> + +#ifdef QT_SYMBIAN_BLUETOOTH +#include <es_sock.h> +#include <bt_sock.h> +#endif //QT_SYMBIAN_BLUETOOTH + +#ifdef QT_BLUEZ_BLUETOOTH +QT_FORWARD_DECLARE_CLASS(QSocketNotifier) +#endif + +QT_BEGIN_HEADER + +class QBluetoothAddress; +class QBluetoothSocket; + +#ifdef QT_SYMBIAN_BLUETOOTH +class QBluetoothSocketPrivate; +#endif + +class QL2capServer; + +class QL2capServerPrivate +{ + Q_DECLARE_PUBLIC(QL2capServer) + +public: + QL2capServerPrivate(); + ~QL2capServerPrivate(); + +#ifdef QT_SYMBIAN_BLUETOOTH + // private slots + void _q_connected(); + void _q_socketError(QBluetoothSocket::SocketError err); + void _q_disconnected(); +#endif //QT_SYMBIAN_BLUETOOTH + +#ifdef QT_BLUEZ_BLUETOOTH + void _q_newConnection(); +#endif + + +public: + QBluetoothSocket *socket; + bool pending; + + int maxPendingConnections; + QBluetooth::SecurityFlags securityFlags; + +#ifdef QT_SYMBIAN_BLUETOOTH + mutable QList<QBluetoothSocket *> activeSockets; + QBluetoothSocketPrivate *ds; +#endif //QT_SYMBIAN_BLUETOOTH + +protected: + QL2capServer *q_ptr; + +private: +#ifdef QT_BLUEZ_BLUETOOTH + QSocketNotifier *socketNotifier; +#endif +}; + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/ql2capserver_symbian.cpp b/src/bluetooth/ql2capserver_symbian.cpp new file mode 100644 index 00000000..1b35740b --- /dev/null +++ b/src/bluetooth/ql2capserver_symbian.cpp @@ -0,0 +1,285 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "ql2capserver.h" +#include "ql2capserver_p.h" +#include "qbluetoothsocket.h" +#include "qbluetoothsocket_p.h" +#include "symbian/utils_symbian_p.h" + +#include <QTimer> +#include <QCoreApplication> + +#include <QDebug> + +QL2capServerPrivate::QL2capServerPrivate() +: socket(0),pending(false),maxPendingConnections(1),securityFlags(QBluetooth::NoSecurity) +{ +} + +QL2capServerPrivate::~QL2capServerPrivate() +{ + delete socket; +} + +void QL2capServer::close() +{ + Q_D(QL2capServer); + if(!d->socket) + { + // there is no way to propagate the error to user + // so just ignore the problem. + return; + } + d->socket->setSocketState(QBluetoothSocket::ClosingState); + d->socket->close(); + // force active object (socket) to run and shutdown socket. + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); +} + +bool QL2capServer::listen(const QBluetoothAddress &address, quint16 port) +{ + Q_D(QL2capServer); + // listen has already been called before + if(d->socket) + return true; + + d->socket = new QBluetoothSocket(QBluetoothSocket::L2capSocket,this); + + if(!d->socket) + { + return false; + } + + d->ds = d->socket->d_ptr; + + if(!d->ds) + { + delete d->socket; + d->socket = 0; + return false; + } + + TL2CAPSockAddr addr; + + if(!address.isNull()) + { + // TBTDevAddr constructor may panic + TRAPD(err,addr.SetBTAddr(TBTDevAddr(address.toUInt64()))); + if(err != KErrNone) + { + delete d->socket; + d->socket = 0; + return false; + } + } + + if (port == 0) + addr.SetPort(KL2CAPPassiveAutoBind); + else + addr.SetPort(port); + + TBTServiceSecurity security; + switch (d->securityFlags) { + case QBluetooth::Authentication: + security.SetAuthentication(EMitmDesired); + break; + case QBluetooth::Authorization: + security.SetAuthorisation(ETrue); + break; + case QBluetooth::Encryption: + // "Secure" is BlueZ specific we just make sure the code remain compatible + case QBluetooth::Secure: + // authentication required + security.SetAuthentication(EMitmDesired); + security.SetEncryption(ETrue); + break; + case QBluetooth::NoSecurity: + default: + break; + } + addr.SetSecurity(security); + if(d->ds->iSocket->Bind(addr) == KErrNone) + { + d->socket->setSocketState(QBluetoothSocket::BoundState); + } + else + { + delete d->socket; + d->socket = 0; + return false; + } + + if(d->ds->iSocket->Listen(d->maxPendingConnections) != KErrNone) + { + delete d->socket; + d->socket = 0; + return false; + } + // unknown socket type is used for blank socket + QBluetoothSocket *pendingSocket = new QBluetoothSocket(QBluetoothSocket::UnknownSocketType, this); + if(!pendingSocket) + { + delete d->socket; + d->socket = 0; + return false; + } + QBluetoothSocketPrivate *pd = pendingSocket->d_ptr; + pd->ensureBlankNativeSocket(QBluetoothSocket::L2capSocket); + connect(d->socket, SIGNAL(disconnected()), this, SLOT(disconnected())); + connect(d->socket, SIGNAL(connected()), this, SLOT(connected())); + connect(d->socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(socketError(QBluetoothSocket::SocketError))); + if (d->ds->iSocket->Accept(*pd->iSocket) == KErrNone) + { + d->socket->setSocketState(QBluetoothSocket::ListeningState); + d->activeSockets.append(pendingSocket); + return true; + } + else + { + delete d->socket, pendingSocket; + d->socket = 0; + return false; + } +} + +void QL2capServer::setMaxPendingConnections(int numConnections) +{ + Q_D(QL2capServer); + d->maxPendingConnections = numConnections; +} + +bool QL2capServer::hasPendingConnections() const +{ + Q_D(const QL2capServer); + return !d->activeSockets.isEmpty(); +} + +QBluetoothSocket *QL2capServer::nextPendingConnection() +{ + Q_D(QL2capServer); + + if (d->activeSockets.isEmpty()) + return 0; + + QBluetoothSocket *next = d->activeSockets.takeFirst(); + return next; +} + +QBluetoothAddress QL2capServer::serverAddress() const +{ + Q_D(const QL2capServer); + if(d->socket) + return d->socket->localAddress(); + else + return QBluetoothAddress(); +} + +quint16 QL2capServer::serverPort() const +{ + Q_D(const QL2capServer); + if(d->socket) + return d->socket->localPort(); + else + return 0; +} + +void QL2capServerPrivate::_q_connected() +{ + Q_Q(QL2capServer); + if(!activeSockets.isEmpty()) + { + // update state of the pending socket and start receiving + (activeSockets.last())->setSocketState(QBluetoothSocket::ConnectedState); + (activeSockets.last())->d_ptr->startReceive(); + } + else + return; + emit q->newConnection(); + QBluetoothSocket *pendingSocket = new QBluetoothSocket(QBluetoothSocket::UnknownSocketType); + if(!pendingSocket) + { + delete socket; + socket = 0; + return; + } + QBluetoothSocketPrivate *pd = pendingSocket->d_ptr; + pd->ensureBlankNativeSocket(QBluetoothSocket::L2capSocket); + if (ds->iSocket->Accept(*pd->iSocket) == KErrNone) + { + socket->setSocketState(QBluetoothSocket::ListeningState); + activeSockets.append(pendingSocket); + return; + } + else + { + // we might reach this statement if we have reach + // maxPendingConnections + qDebug() << "QL2capServer::connected accept failed"; + delete socket, pendingSocket; + socket = 0; + return; + } +} + +void QL2capServerPrivate::_q_disconnected() +{ + delete socket; + socket = 0; +} + +void QL2capServerPrivate::_q_socketError(QBluetoothSocket::SocketError err) +{ + delete socket; + socket = 0; +} + +void QL2capServer::setSecurityFlags(QBluetooth::SecurityFlags security) +{ + Q_D(QL2capServer); + d->securityFlags = security; +} + +QBluetooth::SecurityFlags QL2capServer::securityFlags() const +{ + Q_D(const QL2capServer); + return d->securityFlags; +} diff --git a/src/bluetooth/ql2capsocket.cpp b/src/bluetooth/ql2capsocket.cpp new file mode 100644 index 00000000..dda5af05 --- /dev/null +++ b/src/bluetooth/ql2capsocket.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "ql2capsocket.h" + +QL2capSocket::QL2capSocket(QObject *parent) +: QBluetoothSocket(parent) +{ +} + +#include "moc_ql2capsocket.cpp" diff --git a/src/bluetooth/ql2capsocket.h b/src/bluetooth/ql2capsocket.h new file mode 100644 index 00000000..cf63b62e --- /dev/null +++ b/src/bluetooth/ql2capsocket.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QL2CAPSOCKET_H +#define QL2CAPSOCKET_H + +#include <qbluetoothsocket.h> +#include <qbluetoothaddress.h> + +#include <QtCore/QObject> + +QT_BEGIN_HEADER + +class QL2capSocket : public QBluetoothSocket +{ + Q_OBJECT + +public: + explicit QL2capSocket(QObject *parent = 0); + + bool hasPendingDatagrams() const; + qint64 pendingDatagramSize() const; + qint64 readDatagram(char *data, qint64 maxlen, QBluetoothAddress *host = 0, quint16 *port = 0); + qint64 writeDatagram(const char *data, qint64 len, const QBluetoothAddress &host, + quint16 port); + inline qint64 writeDatagram(const QByteArray &datagram, const QBluetoothAddress &host, + quint16 port) + { return writeDatagram(datagram.constData(), datagram.size(), host, port); } + +private: + Q_DISABLE_COPY(QL2capSocket) +}; + +QT_END_HEADER + +#endif // QL2CAPSOCKET_H diff --git a/src/bluetooth/qrfcommserver.cpp b/src/bluetooth/qrfcommserver.cpp new file mode 100644 index 00000000..cc3e4e35 --- /dev/null +++ b/src/bluetooth/qrfcommserver.cpp @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qrfcommserver.h" +#include "qrfcommserver_p.h" +#include "qbluetoothsocket.h" + +/*! + \class QRfcommServer + \brief The QRfcommServer class provides an RFCOMM server. + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity + \since 5.0 + + QRfcommServer is used to implement Bluetooth services over RFCOMM. + + Start listening for incoming connections with listen(). The newConnection() signal is emitted + when a new connection is established. Call nextPendingConnection() to get a QBluetoothSocket + for the new connection. + + To enable other devices to find your service create a QBluetoothServiceInfo with the + applicable attributes for your service and register it with + QBluetoothServiceInfo::registerService(). Call serverPort() to get the RFCOMM channel number + that is being used. + + \sa QBluetoothServiceInfo, QBluetoothSocket +*/ + +/*! + \fn void QRfcommServer::newConnection() + + This signal is emitted when a new connection is available. + + The connected slot should call nextPendingConnection() to get a QBluetoothSocket object to + send and receive data over the connection. + + \sa nextPendingConnection(), hasPendingConnections() +*/ + +/*! + \fn void QRfcommServer::close() + + Closes and resets the listening socket. +*/ + +/*! + \fn bool QRfcommServer::listen(const QBluetoothAddress &address, quint16 port) + + Start listening for incoming connections to \a address on \a port. + + Returns true if the operation succeeded and the RFCOMM server is listening for + incoming connections; otherwise returns false. + + \sa isListening(), newConnection() +*/ + +/*! + \fn void QRfcommServer::setMaxPendingConnections(int numConnections) + + Sets the maximum number of pending connections to \a numConnections. + + \sa maxPendingConnections() +*/ + +/*! + \fn bool QRfcommServer::hasPendingConnections() const + Returns true if a connection is pending; otherwise returns false. +*/ + +/*! + \fn QBluetoothSocket *QRfcommServer::nextPendingConnection() + + Returns a pointer QBluetoothSocket for the next pending connection. It is the callers + responsibility to delete pointer. +*/ + +/*! + \fn QBluetoothAddress QRfcommServer::serverAddress() const + + Returns the server address. +*/ + +/*! + \fn quint16 QRfcommServer::serverPort() const + + Returns the server's port number. +*/ + +/*! + Constructs an RFCOMM server with \a parent. +*/ +QRfcommServer::QRfcommServer(QObject *parent) + : QObject(parent), d_ptr(new QRfcommServerPrivate) +{ + d_ptr->q_ptr = this; +} + +/*! + Destroys the RFCOMM server. +*/ +QRfcommServer::~QRfcommServer() +{ + delete d_ptr; +} + +/*! + Returns true if the RFCOMM server is listening for incoming connections; otherwise returns + false. +*/ +bool QRfcommServer::isListening() const +{ + Q_D(const QRfcommServer); + + return d->socket->state() == QBluetoothSocket::ListeningState; +} + +/*! + Returns the maximum number of pending connections. + + \sa setMaxPendingConnections() +*/ +int QRfcommServer::maxPendingConnections() const +{ + Q_D(const QRfcommServer); + + return d->maxPendingConnections; +} + +/*! + \fn QRfcommServer::setSecurityFlags(QBluetooth::SecurityFlags security) + Sets the Bluetooth security flags to \a security. This function must be called prior to calling + listen(). +*/ + +/*! + \fn QBluetooth::SecurityFlags QRfcommServer::securityFlags() const + Returns the Bluetooth security flags. +*/ + +#include "moc_qrfcommserver.cpp" diff --git a/src/bluetooth/qrfcommserver.h b/src/bluetooth/qrfcommserver.h new file mode 100644 index 00000000..87676649 --- /dev/null +++ b/src/bluetooth/qrfcommserver.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QRFCOMMSERVER_H +#define QRFCOMMSERVER_H + +#include "../qtconnectivityglobal.h" + +#include <QObject> + +#include <qbluetoothaddress.h> +#include <qbluetooth.h> +#include <qbluetoothsocket.h> + +QT_BEGIN_HEADER + +class QRfcommServerPrivate; +class QBluetoothSocket; + +class Q_CONNECTIVITY_EXPORT QRfcommServer : public QObject +{ + Q_OBJECT + +public: + QRfcommServer(QObject *parent = 0); + ~QRfcommServer(); + + void close(); + + bool listen(const QBluetoothAddress &address = QBluetoothAddress(), quint16 port = 0); + bool isListening() const; + + void setMaxPendingConnections(int numConnections); + int maxPendingConnections() const; + + bool hasPendingConnections() const; + QBluetoothSocket *nextPendingConnection(); + + QBluetoothAddress serverAddress() const; + quint16 serverPort() const; + + void setSecurityFlags(QBluetooth::SecurityFlags security); + QBluetooth::SecurityFlags securityFlags() const; + +signals: + void newConnection(); + +protected: + QRfcommServerPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QRfcommServer) + +#ifdef QT_SYMBIAN_BLUETOOTH + Q_PRIVATE_SLOT(d_func(), void _q_connected()) + Q_PRIVATE_SLOT(d_func(), void _q_socketError(QBluetoothSocket::SocketError err)) + Q_PRIVATE_SLOT(d_func(), void _q_disconnected()) +#endif //QT_SYMBIAN_BLUETOOTH + +#ifdef QT_BLUEZ_BLUETOOTH + Q_PRIVATE_SLOT(d_func(), void _q_newConnection()) +#endif +}; + + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/qrfcommserver_bluez.cpp b/src/bluetooth/qrfcommserver_bluez.cpp new file mode 100644 index 00000000..0f5dff02 --- /dev/null +++ b/src/bluetooth/qrfcommserver_bluez.cpp @@ -0,0 +1,248 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qrfcommserver.h" +#include "qrfcommserver_p.h" +#include "qbluetoothsocket.h" + +#include <QtCore/QSocketNotifier> + +#include <QtCore/QDebug> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/rfcomm.h> + +#include <errno.h> + +static inline void convertAddress(quint64 from, quint8 (&to)[6]) +{ + to[0] = (from >> 0) & 0xff; + to[1] = (from >> 8) & 0xff; + to[2] = (from >> 16) & 0xff; + to[3] = (from >> 24) & 0xff; + to[4] = (from >> 32) & 0xff; + to[5] = (from >> 40) & 0xff; +} + +QRfcommServerPrivate::QRfcommServerPrivate() +: maxPendingConnections(1), socketNotifier(0) +{ + socket = new QBluetoothSocket(QBluetoothSocket::RfcommSocket); +} + +QRfcommServerPrivate::~QRfcommServerPrivate() +{ + delete socketNotifier; + + delete socket; +} + +void QRfcommServerPrivate::_q_newConnection() +{ + // disable socket notifier until application calls nextPendingConnection(). + socketNotifier->setEnabled(false); + + emit q_ptr->newConnection(); +} + +void QRfcommServer::close() +{ + Q_D(QRfcommServer); + + delete d->socketNotifier; + d->socketNotifier = 0; + + d->socket->close(); +} + +bool QRfcommServer::listen(const QBluetoothAddress &address, quint16 port) +{ + Q_D(QRfcommServer); + + int sock = d->socket->socketDescriptor(); + if (sock < 0) + return false; + + sockaddr_rc addr; + + addr.rc_family = AF_BLUETOOTH; + addr.rc_channel = port; + + if (!address.isNull()) + convertAddress(address.toUInt64(), addr.rc_bdaddr.b); + else + convertAddress(Q_UINT64_C(0), addr.rc_bdaddr.b); + + if (::bind(sock, reinterpret_cast<sockaddr *>(&addr), sizeof(sockaddr_rc)) < 0) + return false; + + if (::listen(sock, d->maxPendingConnections) < 0) + return false; + + d->socket->setSocketState(QBluetoothSocket::ListeningState); + + if (!d->socketNotifier) { + d->socketNotifier = new QSocketNotifier(d->socket->socketDescriptor(), + QSocketNotifier::Read); + connect(d->socketNotifier, SIGNAL(activated(int)), this, SLOT(_q_newConnection())); + } + + return true; +} + +void QRfcommServer::setMaxPendingConnections(int numConnections) +{ + Q_D(QRfcommServer); + + if (d->socket->state() == QBluetoothSocket::UnconnectedState) + d->maxPendingConnections = numConnections; +} + +bool QRfcommServer::hasPendingConnections() const +{ + Q_D(const QRfcommServer); + + if (!d || !d->socketNotifier) + return false; + + // if the socket notifier is disable there is a pending connection waiting for us to accept. + return !d->socketNotifier->isEnabled(); +} + +QBluetoothSocket *QRfcommServer::nextPendingConnection() +{ + Q_D(QRfcommServer); + + if (!hasPendingConnections()) + return 0; + + sockaddr_rc addr; + socklen_t length = sizeof(sockaddr_rc); + + int pending = ::accept(d->socket->socketDescriptor(), + reinterpret_cast<sockaddr *>(&addr), &length); + if (pending >= 0) { + QBluetoothSocket *newSocket = new QBluetoothSocket; + newSocket->setSocketDescriptor(pending, QBluetoothSocket::RfcommSocket); + + d->socketNotifier->setEnabled(true); + + return newSocket; + } else { + qDebug() << "Hmm, could have sworn there was a connection waiting to be accepted!"; + d->socketNotifier->setEnabled(true); + } + + return 0; +} + +QBluetoothAddress QRfcommServer::serverAddress() const +{ + Q_D(const QRfcommServer); + + return d->socket->localAddress(); +} + +quint16 QRfcommServer::serverPort() const +{ + Q_D(const QRfcommServer); + + return d->socket->localPort(); +} + +void QRfcommServer::setSecurityFlags(QBluetooth::SecurityFlags security) +{ + Q_D(QRfcommServer); + + int lm = 0; + if(security == QBluetooth::NoSecurity){ + lm = 0; + } + if(security.testFlag(QBluetooth::Authorization)){ + lm |= RFCOMM_LM_AUTH; + } + if(security.testFlag(QBluetooth::Authentication)) { + lm |= RFCOMM_LM_TRUSTED; + } + if(security.testFlag(QBluetooth::Encryption)){ + lm |= RFCOMM_LM_ENCRYPT; + } + if(security.testFlag(QBluetooth::Secure)){ + lm |= RFCOMM_LM_SECURE; + } + + qDebug() << hex << "Setting lm to" << lm << security; + + if(setsockopt(d->socket->socketDescriptor(), SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0){ + qWarning() << "Failed to set socket option, closing socket for safety" << errno; + qWarning() << "Error: " << strerror(errno); + d->socket->close(); + } +} + +QBluetooth::SecurityFlags QRfcommServer::securityFlags() const +{ + Q_D(const QRfcommServer); + + int lm = 0; + int len = sizeof(lm); + int security = QBluetooth::NoSecurity; + + if(getsockopt(d->socket->socketDescriptor(), SOL_RFCOMM, RFCOMM_LM, &lm, (socklen_t *)&len) < 0) { + qWarning() << "Failed to get security flags" << strerror(errno); + return QBluetooth::NoSecurity; + } + + if(lm & RFCOMM_LM_SECURE) + security |= QBluetooth::Secure; + + if(lm & RFCOMM_LM_ENCRYPT) + security |= QBluetooth::Encryption; + + if(lm & RFCOMM_LM_TRUSTED) + security |= QBluetooth::Authentication; + + if(lm & RFCOMM_LM_AUTH) + security |= QBluetooth::Authorization; + + return static_cast<QBluetooth::Security>(security); +} + diff --git a/src/bluetooth/qrfcommserver_p.cpp b/src/bluetooth/qrfcommserver_p.cpp new file mode 100644 index 00000000..6b7d1aab --- /dev/null +++ b/src/bluetooth/qrfcommserver_p.cpp @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qrfcommserver.h" +#include "qrfcommserver_p.h" +#include "qbluetoothsocket.h" + +QRfcommServerPrivate::QRfcommServerPrivate() +{ +} + +QRfcommServerPrivate::~QRfcommServerPrivate() +{ +} + +void QRfcommServer::close() +{ +} + +bool QRfcommServer::listen(const QBluetoothAddress &address, quint16 port) +{ + Q_UNUSED(address); + Q_UNUSED(port); + return false; +} + +void QRfcommServer::setMaxPendingConnections(int numConnections) +{ + Q_UNUSED(numConnections); +} + +bool QRfcommServer::hasPendingConnections() const +{ + return false; +} + +QBluetoothSocket *QRfcommServer::nextPendingConnection() +{ + return 0; +} + +QBluetoothAddress QRfcommServer::serverAddress() const +{ + return QBluetoothAddress(); +} + +quint16 QRfcommServer::serverPort() const +{ + return 0; +} + + +#ifdef QT_BLUEZ_BLUETOOTH +void QRfcommServerPrivate::_q_newConnection() +{ +} +#endif + + +#ifdef QT_SYMBIAN_BLUETOOTH +void QRfcommServerPrivate::HandleAcceptCompleteL(TInt aErr) +{ +} +void QRfcommServerPrivate::HandleActivateBasebandEventNotifierCompleteL(TInt aErr, TBTBasebandEventNotification &aEventNotification) +{ +} +void QRfcommServerPrivate::HandleConnectCompleteL(TInt aErr) +{ +} +void QRfcommServerPrivate::HandleIoctlCompleteL(TInt aErr) +{ +} +void QRfcommServerPrivate::HandleReceiveCompleteL(TInt aErr) +{ +} +void QRfcommServerPrivate::HandleSendCompleteL(TInt aErr) +{ +} +void QRfcommServerPrivate::HandleShutdownCompleteL(TInt aErr) +{ +} +#endif + +void QRfcommServer::setSecurityFlags(QBluetooth::SecurityFlags security) +{ +} + +QBluetooth::SecurityFlags QRfcommServer::securityFlags() const +{ + return QBluetooth::NoSecurity; +} + diff --git a/src/bluetooth/qrfcommserver_p.h b/src/bluetooth/qrfcommserver_p.h new file mode 100644 index 00000000..a4ea301e --- /dev/null +++ b/src/bluetooth/qrfcommserver_p.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QRFCOMMSERVER_P_H +#define QRFCOMMSERVER_P_H + +#include <QtGlobal> +#include <QList> +#include <qbluetoothsocket.h> + +#ifdef QT_SYMBIAN_BLUETOOTH +#include <es_sock.h> +#include <bt_sock.h> +#endif + +#ifdef QT_BLUEZ_BLUETOOTH +QT_FORWARD_DECLARE_CLASS(QSocketNotifier) +#endif + +QT_BEGIN_HEADER + +class QBluetoothAddress; +class QBluetoothSocket; + +#ifdef QT_SYMBIAN_BLUETOOTH +class QBluetoothSocketPrivate; +#endif + +class QRfcommServer; + +class QRfcommServerPrivate +{ + Q_DECLARE_PUBLIC(QRfcommServer) + +public: + QRfcommServerPrivate(); + ~QRfcommServerPrivate(); + +#ifdef QT_SYMBIAN_BLUETOOTH + // private slots + void _q_connected(); + void _q_socketError(QBluetoothSocket::SocketError err); + void _q_disconnected(); +#endif //QT_SYMBIAN_BLUETOOTH + +#ifdef QT_BLUEZ_BLUETOOTH + void _q_newConnection(); +#endif + +public: + QBluetoothSocket *socket; + +#ifdef QT_SYMBIAN_BLUETOOTH + mutable QList<QBluetoothSocket *> activeSockets; + QBluetoothSocketPrivate *ds; +#endif + + int maxPendingConnections; + QBluetooth::SecurityFlags securityFlags; + +protected: + QRfcommServer *q_ptr; + +private: +#ifdef QT_BLUEZ_BLUETOOTH + QSocketNotifier *socketNotifier; +#endif +}; + +QT_END_HEADER + +#endif diff --git a/src/bluetooth/qrfcommserver_symbian.cpp b/src/bluetooth/qrfcommserver_symbian.cpp new file mode 100644 index 00000000..0f5c4506 --- /dev/null +++ b/src/bluetooth/qrfcommserver_symbian.cpp @@ -0,0 +1,284 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qrfcommserver.h" +#include "qrfcommserver_p.h" +#include "qbluetoothsocket.h" +#include "qbluetoothsocket_p.h" +#include "qbluetoothlocaldevice.h" +#include "symbian/utils_symbian_p.h" + +#include <QTimer> +#include <QCoreApplication> + +#include <QDebug> + +QRfcommServerPrivate::QRfcommServerPrivate() +: socket(0),maxPendingConnections(1),securityFlags(QBluetooth::NoSecurity) +{ +} + +QRfcommServerPrivate::~QRfcommServerPrivate() +{ + delete socket; +} + +void QRfcommServer::close() +{ + Q_D(QRfcommServer); + if(!d->socket) + { + // there is no way to propagate the error to user + // so just ignore the problem. + return; + } + d->socket->setSocketState(QBluetoothSocket::ClosingState); + d->socket->close(); + // force active object (socket) to run and shutdown socket. + qApp->processEvents(QEventLoop::ExcludeUserInputEvents); +} + +bool QRfcommServer::listen(const QBluetoothAddress &address, quint16 port) +{ + Q_D(QRfcommServer); + // listen has already been called before + if(d->socket) + return true; + + d->socket = new QBluetoothSocket(QBluetoothSocket::RfcommSocket,this); + + if(!d->socket) + { + return false; + } + + d->ds = d->socket->d_ptr; + + if(!d->ds) + { + delete d->socket; + d->socket = 0; + return false; + } + + d->ds->ensureNativeSocket(QBluetoothSocket::RfcommSocket); + + TRfcommSockAddr addr; + if(!address.isNull()) + { + // TBTDevAddr constructor may panic + TRAPD(err,addr.SetBTAddr(TBTDevAddr(address.toUInt64()))); + if(err != KErrNone) + { + delete d->socket; + d->socket = 0; + return false; + } + } + + if (port == 0) + addr.SetPort(KRfcommPassiveAutoBind); + else + addr.SetPort(port); + + TBTServiceSecurity security; + switch (d->securityFlags) { + case QBluetooth::Authentication: + security.SetAuthentication(EMitmDesired); + break; + case QBluetooth::Authorization: + security.SetAuthorisation(ETrue); + break; + case QBluetooth::Encryption: + // "Secure" is BlueZ specific we just make sure the code remain compatible + case QBluetooth::Secure: + // authentication required + security.SetAuthentication(EMitmDesired); + security.SetEncryption(ETrue); + break; + case QBluetooth::NoSecurity: + default: + break; + } + if(d->ds->iSocket->Bind(addr) == KErrNone) + { + d->socket->setSocketState(QBluetoothSocket::BoundState); + } + else + { + delete d->socket; + d->socket = 0; + return false; + } + + if(d->ds->iSocket->Listen(d->maxPendingConnections) != KErrNone) + { + delete d->socket; + d->socket = 0; + return false; + } + + QBluetoothSocket *pendingSocket = new QBluetoothSocket(QBluetoothSocket::UnknownSocketType, this); + if(!pendingSocket) + { + delete d->socket; + d->socket = 0; + return false; + } + QBluetoothSocketPrivate *pd = pendingSocket->d_ptr; + pd->ensureBlankNativeSocket(QBluetoothSocket::RfcommSocket); + connect(d->socket, SIGNAL(disconnected()), this, SLOT(_q_disconnected())); + connect(d->socket, SIGNAL(connected()), this, SLOT(_q_connected())); + connect(d->socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(_q_socketError(QBluetoothSocket::SocketError))); + if (d->ds->iSocket->Accept(*pd->iSocket) == KErrNone) + { + d->socket->setSocketState(QBluetoothSocket::ListeningState); + d->activeSockets.append(pendingSocket); + return true; + } + else + { + delete d->socket, pendingSocket; + d->socket = 0; + return false; + } +} + +void QRfcommServer::setMaxPendingConnections(int numConnections) +{ + Q_D(QRfcommServer); + d->maxPendingConnections = numConnections; +} + +QBluetoothAddress QRfcommServer::serverAddress() const +{ + Q_D(const QRfcommServer); + if(d->socket) + return d->socket->localAddress(); + else + return QBluetoothAddress(); +} + +quint16 QRfcommServer::serverPort() const +{ + Q_D(const QRfcommServer); + if(d->socket) + return d->socket->localPort(); + else + return 0; +} + +bool QRfcommServer::hasPendingConnections() const +{ + Q_D(const QRfcommServer); + return !d->activeSockets.isEmpty(); +} + +QBluetoothSocket *QRfcommServer::nextPendingConnection() +{ + Q_D(QRfcommServer); + if (d->activeSockets.isEmpty()) + return 0; + + QBluetoothSocket *next = d->activeSockets.takeFirst(); + return next; +} + +void QRfcommServerPrivate::_q_connected() +{ + Q_Q(QRfcommServer); + if(!activeSockets.isEmpty()) + { + // update state of the pending socket and start receiving + (activeSockets.last())->setSocketState(QBluetoothSocket::ConnectedState); + (activeSockets.last())->d_ptr->startReceive(); + } + else + return; + emit q->newConnection(); + QBluetoothSocket *pendingSocket = new QBluetoothSocket(QBluetoothSocket::UnknownSocketType); + if(!pendingSocket) + { + delete socket; + socket = 0; + return; + } + QBluetoothSocketPrivate *pd = pendingSocket->d_ptr; + pd->ensureBlankNativeSocket(QBluetoothSocket::RfcommSocket); + if (ds->iSocket->Accept(*pd->iSocket) == KErrNone) + { + socket->setSocketState(QBluetoothSocket::ListeningState); + activeSockets.append(pendingSocket); + return; + } + else + { + // we might reach this statement if we have reach + // maxPendingConnections + delete socket, pendingSocket; + socket = 0; + return; + } +} + +void QRfcommServerPrivate::_q_disconnected() +{ + delete socket; + socket = 0; +} + +void QRfcommServerPrivate::_q_socketError(QBluetoothSocket::SocketError err) +{ + delete socket; + socket = 0; +} + +void QRfcommServer::setSecurityFlags(QBluetooth::SecurityFlags security) +{ + Q_D(QRfcommServer); + d->securityFlags = security; +} + +QBluetooth::SecurityFlags QRfcommServer::securityFlags() const +{ + Q_D(const QRfcommServer); + return d->securityFlags; +} diff --git a/src/bluetooth/qrfcommsocket.cpp b/src/bluetooth/qrfcommsocket.cpp new file mode 100644 index 00000000..0c9b4ba3 --- /dev/null +++ b/src/bluetooth/qrfcommsocket.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qrfcommsocket.h" + +QRfcommSocket::QRfcommSocket(QObject *parent) +: QBluetoothSocket(parent) +{ +} + +#include "moc_qrfcommsocket.cpp" diff --git a/src/bluetooth/qrfcommsocket.h b/src/bluetooth/qrfcommsocket.h new file mode 100644 index 00000000..eaf25514 --- /dev/null +++ b/src/bluetooth/qrfcommsocket.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QRFCOMMSOCKET_H +#define QRFCOMMSOCKET_H + +#include <qbluetoothsocket.h> + +QT_BEGIN_HEADER + +class QRfcommSocket : public QBluetoothSocket +{ + Q_OBJECT + +public: + explicit QRfcommSocket(QObject *parent = 0); + +private: + Q_DISABLE_COPY(QRfcommSocket) +}; + +QT_END_HEADER + +#endif // QRFCOMMSOCKET_H diff --git a/src/bluetooth/qtbluetoothversion.h b/src/bluetooth/qtbluetoothversion.h new file mode 100644 index 00000000..346b28e1 --- /dev/null +++ b/src/bluetooth/qtbluetoothversion.h @@ -0,0 +1,9 @@ +/* This file was generated by syncqt with the info from sync.profile. */ +#ifndef QT_QTBLUETOOTH_VERSION_H +#define QT_QTBLUETOOTH_VERSION_H + +#define QTBLUETOOTH_VERSION_STR "5.0.0" + +#define QTBLUETOOTH_VERSION 0x050000 + +#endif // QT_QTBLUETOOTH_VERSION_H diff --git a/src/bluetooth/symbian/bluetoothlinkmanagerdevicediscoverer.cpp b/src/bluetooth/symbian/bluetoothlinkmanagerdevicediscoverer.cpp new file mode 100644 index 00000000..96fa4245 --- /dev/null +++ b/src/bluetooth/symbian/bluetoothlinkmanagerdevicediscoverer.cpp @@ -0,0 +1,387 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// INCLUDE FILES +#include "bluetoothlinkmanagerdevicediscoverer.h" +#include "qbluetoothaddress.h" +#include "qbluetoothdeviceinfo.h" +#include "qbluetoothuuid.h" + +#include <qstring.h> +#ifdef EIR_SUPPORTED +#include <arpa/inet.h> +#include <netinet/in.h> +#endif +#include "utils_symbian_p.h" +#include <qdebug.h> + +/*! \internal + \class BluetoothLinkManagerDeviceDiscoverer + \brief The BluetoothLinkManagerDeviceDiscoverer class searches other bluetooth devices. + \since 5.0 + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity + \internal + + BluetoothLinkManagerDeviceDiscoverer is an Symbian ActiveObject derived class that discovers + other Bluetooth devices using "BTLinkManager" protocol. + + When Bluetoothdevices are found signal deviceDiscovered(QBluetoothDeviceInfo &) is emitted. When + all devices are found (or none) signal deviceDiscoveryComplete() is emitted. + + In case of an error signal linkManagerError(int error) is emitted. In the case of errorSignal + one should consider deleting this class and creating it again. +*/ + +_LIT(KBTLinkManagerTxt,"BTLinkManager"); + +BluetoothLinkManagerDeviceDiscoverer::BluetoothLinkManagerDeviceDiscoverer(RSocketServ &socketServer,QObject *parent) + : QObject(parent) + , CActive(CActive::EPriorityStandard) + , m_socketServer(socketServer) + , m_pendingCancel(false), m_pendingStart(false), m_discoveryType (0) +{ + TInt result; + + /* find Bluetooth protocol */ + TProtocolDesc protocol; + result = m_socketServer.FindProtocol(KBTLinkManagerTxt(),protocol); + if (result == KErrNone) { + /* Create and initialise an RHostResolver */ + result = m_hostResolver.Open(m_socketServer, protocol.iAddrFamily, protocol.iProtocol); + } + // check possible error + if (result != KErrNone) { + setError(result); + } + + //add this active object to scheduler + CActiveScheduler::Add(this); +} + +BluetoothLinkManagerDeviceDiscoverer::~BluetoothLinkManagerDeviceDiscoverer() +{ + // cancel active object + Cancel(); + m_hostResolver.Close(); +} +/*! + Starts up device discovery. When devices are discovered signal deviceDiscovered is emitted. + After signal deviceDiscoveryComplete() is emitted new discovery request can be made. +*/ +void BluetoothLinkManagerDeviceDiscoverer::startDiscovery(const uint discoveryType) +{ + m_discoveryType = discoveryType; + + if(m_pendingCancel == true) { + m_pendingStart = true; + m_pendingCancel = false; + return; + } + if (!IsActive()) { + m_addr.SetIAC( discoveryType ); +#ifdef EIR_SUPPORTED + m_addr.SetAction(KHostResInquiry | KHostResName | KHostResIgnoreCache | KHostResEir); +#else + m_addr.SetAction(KHostResInquiry | KHostResName | KHostResIgnoreCache); +#endif + m_hostResolver.GetByAddress(m_addr, m_entry, iStatus); + SetActive(); + } +} + +void BluetoothLinkManagerDeviceDiscoverer::stopDiscovery() +{ + m_pendingStart = false; + if (IsActive() && !m_pendingCancel) { + m_pendingCancel = true; + m_hostResolver.Cancel(); + } +} + +/*! + Informs that our request has been prosessed and the data is available to be used. +*/ +void BluetoothLinkManagerDeviceDiscoverer::RunL() +{ + qDebug() << __PRETTY_FUNCTION__ << iStatus.Int(); + switch (iStatus.Int()) { + case KErrNone: // found device + if (m_pendingCancel && !m_pendingStart) { + m_pendingCancel = false; + emit canceled(); + } else { + m_pendingCancel = false; + m_pendingStart = false; + // get next (possible) discovered device + m_hostResolver.Next(m_entry, iStatus); + SetActive(); + emit deviceDiscovered(currentDeviceDataToQBluetoothDeviceInfo()); + } + break; + case KErrHostResNoMoreResults: // done with search + if (m_pendingCancel && !m_pendingStart){ // search was canceled prior to finishing + m_pendingCancel = false; + m_pendingStart = false; + emit canceled(); + } + else if (m_pendingStart){ // search was restarted just prior to finishing + m_pendingStart = false; + m_pendingCancel = false; + startDiscovery(m_discoveryType); + } else { // search completed normally + m_pendingStart = false; + m_pendingCancel = false; + emit deviceDiscoveryComplete(); + } + break; + case KErrCancel: // user canceled search + if (m_pendingStart){ // user activated search after cancel + m_pendingStart = false; + m_pendingCancel = false; + startDiscovery(m_discoveryType); + } else { // standard user cancel case + m_pendingCancel = false; + emit canceled(); + } + break; + default: + m_pendingStart = false; + m_pendingCancel = false; + setError(iStatus.Int()); + } +} +/*! + Cancel current request. +*/ +void BluetoothLinkManagerDeviceDiscoverer::DoCancel() +{ + m_hostResolver.Cancel(); +} + +TInt BluetoothLinkManagerDeviceDiscoverer::RunError(TInt aError) +{ + setError(aError); + return KErrNone; +} + +bool BluetoothLinkManagerDeviceDiscoverer::isReallyActive() const +{ + if(m_pendingStart) + return true; + if(m_pendingCancel) + return false; + return IsActive(); +} + +/*! + Transforms Symbian device name, address and service classes to QBluetootDeviceInfo. +*/ +QBluetoothDeviceInfo BluetoothLinkManagerDeviceDiscoverer::currentDeviceDataToQBluetoothDeviceInfo() const +{ + // extract device information from results and map them to QBluetoothDeviceInfo +#ifdef EIR_SUPPORTED + TBluetoothNameRecordWrapper eir(m_entry()); + TInt bufferlength = 0; + TInt err = KErrNone; + QString deviceName; + bufferlength = eir.GetDeviceNameLength(); + + if (bufferlength > 0) { + TBool nameComplete; + HBufC *deviceNameBuffer = 0; + TRAP(err,deviceNameBuffer = HBufC::NewL(bufferlength)); + if(err) + deviceName = QString(); + else + { + TPtr ptr = deviceNameBuffer->Des(); + err = eir.GetDeviceName(ptr,nameComplete); + if (err == KErrNone /*&& nameComplete*/) + { + if(!nameComplete) + qWarning() << "device name incomplete"; + // isn't it better to get an incomplete name than getting nothing? + deviceName = QString::fromUtf16(ptr.Ptr(), ptr.Length()).toUpper(); + } + else + deviceName = QString(); + delete deviceNameBuffer; + } + } + + QList<QBluetoothUuid> serviceUidList; + RExtendedInquiryResponseUUIDContainer uuidContainer; + QBluetoothDeviceInfo::DataCompleteness completenes = QBluetoothDeviceInfo::DataUnavailable; + + if (eir.GetServiceClassUuids(uuidContainer) == KErrNone) { + TInt uuidCount = uuidContainer.UUIDs().Count(); + if (uuidCount > 0) { + for (int i = 0; i < uuidCount; ++i) { + TPtrC8 shortFormUUid(uuidContainer.UUIDs()[i].ShortestForm()); + if (shortFormUUid.Size() == 2) { + QBluetoothUuid uuid(ntohs(*reinterpret_cast<const quint16 *>(shortFormUUid.Ptr()))); + if (uuidContainer.GetCompleteness(RExtendedInquiryResponseUUIDContainer::EUUID16)) + completenes = QBluetoothDeviceInfo::DataComplete; + else + completenes = QBluetoothDeviceInfo::DataIncomplete; + serviceUidList.append(uuid); + }else if (shortFormUUid.Size() == 4) { + QBluetoothUuid uuid(ntohl(*reinterpret_cast<const quint32 *>(shortFormUUid.Ptr()))); + if (uuidContainer.GetCompleteness(RExtendedInquiryResponseUUIDContainer::EUUID32)) + completenes = QBluetoothDeviceInfo::DataComplete; + else + completenes = QBluetoothDeviceInfo::DataIncomplete; + serviceUidList.append(uuid); + }else if (shortFormUUid.Size() == 16) { + QBluetoothUuid uuid(*reinterpret_cast<const quint128 *>(shortFormUUid.Ptr())); + if (uuidContainer.GetCompleteness(RExtendedInquiryResponseUUIDContainer::EUUID128)) + completenes = QBluetoothDeviceInfo::DataComplete; + else + completenes = QBluetoothDeviceInfo::DataIncomplete; + serviceUidList.append(uuid); + } + } + } + } + uuidContainer.Close(); + + bufferlength = 0; + QByteArray manufacturerData; + bufferlength = eir.GetVendorSpecificDataLength(); + + if (bufferlength > 0) { + HBufC8 *msd = 0; + TRAP(err,msd = HBufC8::NewL(bufferlength)); + if(err) + manufacturerData = QByteArray(); + else + { + TPtr8 temp = msd->Des(); + if (eir.GetVendorSpecificData(temp)) + manufacturerData = s60Desc8ToQByteArray(temp); + else + manufacturerData = QByteArray(); + delete msd; + } + } + + // Get transmission power level + TInt8 transmissionPowerLevel = 0; + eir.GetTxPowerLevel(transmissionPowerLevel); + + // unique address of the device + const TBTDevAddr symbianDeviceAddress = static_cast<TBTSockAddr> (m_entry().iAddr).BTAddr(); + QBluetoothAddress bluetoothAddress = qTBTDevAddrToQBluetoothAddress(symbianDeviceAddress); + + // format symbian major/minor numbers + quint32 deviceClass = qTPackSymbianDeviceClass(m_addr); + + QBluetoothDeviceInfo deviceInfo(bluetoothAddress, deviceName, deviceClass); + + deviceInfo.setRssi(transmissionPowerLevel); + deviceInfo.setServiceUuids(serviceUidList, completenes); + deviceInfo.setManufacturerSpecificData(manufacturerData); +#else + // device name + THostName symbianDeviceName = m_entry().iName; + QString deviceName = QString::fromUtf16(symbianDeviceName.Ptr(), symbianDeviceName.Length()).toUpper(); + + // unique address of the device + const TBTDevAddr symbianDeviceAddress = static_cast<TBTSockAddr> (m_entry().iAddr).BTAddr(); + QBluetoothAddress bluetoothAddress = qTBTDevAddrToQBluetoothAddress(symbianDeviceAddress); + + // format symbian major/minor numbers + quint32 deviceClass = qTPackSymbianDeviceClass(m_addr); + + QBluetoothDeviceInfo deviceInfo(bluetoothAddress, deviceName, deviceClass); + + if (m_addr.Rssi()) + deviceInfo.setRssi(m_addr.Rssi()); +#endif + if (!deviceInfo.rssi()) + deviceInfo.setRssi(1); + + deviceInfo.setCached(false); //TODO cache support missing from devicediscovery API + //qDebug()<< "Discovered device: name="<< deviceName <<", address=" << bluetoothAddress.toString() <<", class=" << deviceClass; + return deviceInfo; +} + +void BluetoothLinkManagerDeviceDiscoverer::setError(int errorCode) +{ + qDebug() << __PRETTY_FUNCTION__ << "errorCode=" << errorCode; + QString errorString; + switch (errorCode) { + case KLinkManagerErrBase: + errorString.append("Link manager base error value or Insufficient baseband resources error value"); + emit linkManagerError(QBluetoothDeviceDiscoveryAgent::UnknownError, errorString); + break; + case KErrProxyWriteNotAvailable: + errorString.append("Proxy write not available error value"); + emit linkManagerError(QBluetoothDeviceDiscoveryAgent::UnknownError, errorString); + break; + case KErrReflexiveBluetoothLink: + errorString.append("Reflexive BT link error value"); + emit linkManagerError(QBluetoothDeviceDiscoveryAgent::UnknownError, errorString); + break; + case KErrPendingPhysicalLink: + errorString.append("Physical link connection already pending when trying to connect the physical link"); + emit linkManagerError(QBluetoothDeviceDiscoveryAgent::UnknownError, errorString); + break; + case KErrNotReady: + errorString.append("KErrNotReady"); + emit linkManagerError(QBluetoothDeviceDiscoveryAgent::UnknownError, errorString); + case KErrCancel: + errorString.append("KErrCancel"); + qDebug() << "emitting canceled"; + emit canceled(); + break; + case KErrNone: + // do nothing + break; + default: + errorString = QString("Symbian errorCode = %1").arg(errorCode); + emit linkManagerError(QBluetoothDeviceDiscoveryAgent::UnknownError, errorString); + break; + } +} +#include "moc_bluetoothlinkmanagerdevicediscoverer.cpp" diff --git a/src/bluetooth/symbian/bluetoothlinkmanagerdevicediscoverer.h b/src/bluetooth/symbian/bluetoothlinkmanagerdevicediscoverer.h new file mode 100644 index 00000000..328222c9 --- /dev/null +++ b/src/bluetooth/symbian/bluetoothlinkmanagerdevicediscoverer.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BLUETOOTHLINKMANAGERDEVICEDISCOVERER_H +#define BLUETOOTHLINKMANAGERDEVICEDISCOVERER_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <qconnectivityglobal.h> +#include <QtCore/QObject> +#include "qbluetoothdevicediscoveryagent.h" + +#include <es_sock.h> +#include <e32base.h> +#include <btdevice.h> +#include <bt_sock.h> +#include <btsdp.h> + + + +QT_BEGIN_HEADER + +class QBluetoothDeviceInfo; + +class BluetoothLinkManagerDeviceDiscoverer : public QObject, public CActive +{ + Q_OBJECT + +public: + + explicit BluetoothLinkManagerDeviceDiscoverer(RSocketServ& aSocketServ, QObject *parent = 0); + ~BluetoothLinkManagerDeviceDiscoverer(); + + void startDiscovery(const uint discoveryType); + void stopDiscovery(); + bool isReallyActive() const; + +protected: // From CActive + void RunL(); + void DoCancel(); + TInt RunError(TInt aError); + +private: + + void setError(int error); + +private: // private helper functions + + QBluetoothDeviceInfo currentDeviceDataToQBluetoothDeviceInfo() const; + +Q_SIGNALS: // SIGNALS + void deviceDiscoveryComplete(); + void deviceDiscovered(const QBluetoothDeviceInfo &device); + void linkManagerError(QBluetoothDeviceDiscoveryAgent::Error error, QString errorString); + void canceled(); + +private: + + // socket server handle + RSocketServ &m_socketServer; + + RHostResolver m_hostResolver; + TInquirySockAddr m_addr; + TNameEntry m_entry; + + TBool m_LIAC; + bool m_pendingCancel; + bool m_pendingStart; + uint m_discoveryType; +}; + +QT_END_HEADER + +#endif //BLUETOOTHLINKMANAGERDEVICEDISCOVERER_H diff --git a/src/bluetooth/symbian/bluetoothsymbianpairingadapter.cpp b/src/bluetooth/symbian/bluetoothsymbianpairingadapter.cpp new file mode 100644 index 00000000..963f45ff --- /dev/null +++ b/src/bluetooth/symbian/bluetoothsymbianpairingadapter.cpp @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// INCLUDE FILES +#include "bluetoothsymbianpairingadapter.h" +#include "qbluetoothaddress.h" +#include "qbluetoothdeviceinfo.h" +#include "qbluetoothlocaldevice.h" +#include <qstring.h> +#include <btdevice.h> +#include "utils_symbian_p.h" +#include "bluetoothsymbianregistryadapter.h" +#include <QDebug> + +/*Dedicated bonding attempt failure when the remote device responds with No-Bonding */ +const static TInt BTKErrRemoteDeviceIndicatedNoBonding = KLinkManagerErrBase-4; +/*! \internal + \class BluetoothSymbianPairingAdapter + \brief The BluetoothSymbianPairingAdapter class is an adapter for bluetooth pairing functionality. + + The BluetoothSymbianPairingAdapter is constructed to use for a one QBluetoothAddress. + It uses following Symbian class CBTEngConnMan for native operations. + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity + \internal +*/ + +BluetoothSymbianPairingAdapter::BluetoothSymbianPairingAdapter(const QBluetoothAddress &address, QObject *parent) + : QObject(parent) + , m_pairingEngine(0) + , m_address(address) + , m_pairingOngoing(false) + , m_errorCode(0) + , m_pairingErrorString() +{ + TRAP(m_errorCode, m_pairingEngine = CBTEngConnMan::NewL(this)) + + if (m_errorCode != KErrNone) + emit pairingError(m_errorCode); +} +BluetoothSymbianPairingAdapter::~BluetoothSymbianPairingAdapter() +{ + delete m_pairingEngine; +} + +int BluetoothSymbianPairingAdapter::errorCode() const +{ + return m_errorCode; +} + +QString BluetoothSymbianPairingAdapter::pairingErrorString() const +{ + return m_pairingErrorString; +} + +void BluetoothSymbianPairingAdapter::startPairing(QBluetoothLocalDevice::Pairing pairing) +{ + TBTDevAddr btAddress(m_address.toUInt64()); + // start async pairing process + m_pairingOngoing = true; + int error = KErrBadHandle; + + if (m_pairingEngine) { + error =KErrNone; + error = m_pairingEngine->PairDevice(btAddress); + } + + if (error != KErrNone) { + PairingComplete(btAddress, error); + } +} + +void BluetoothSymbianPairingAdapter::ConnectComplete( TBTDevAddr& aAddr, TInt aErr, + RBTDevAddrArray* aConflicts ) +{ + Q_UNUSED(aAddr); + Q_UNUSED(aErr); + Q_UNUSED(aConflicts); +} + +void BluetoothSymbianPairingAdapter::DisconnectComplete( TBTDevAddr& aAddr, TInt aErr ) +{ + Q_UNUSED(aAddr); + Q_UNUSED(aErr); +} + +void BluetoothSymbianPairingAdapter::PairingComplete( TBTDevAddr& aAddr, TInt aErr ) +{ + m_pairingErrorString.clear(); + m_pairingOngoing = false; + + switch (aErr) { + case KErrNone: { + // need to figure out if authorized or not + QBluetoothLocalDevice::Pairing pairingStatus = QBluetoothLocalDevice::Paired; + BluetoothSymbianRegistryAdapter *registryAdapter = new BluetoothSymbianRegistryAdapter( + qTBTDevAddrToQBluetoothAddress(aAddr),NULL); + if (registryAdapter) { + pairingStatus = registryAdapter->pairingStatus(); + delete registryAdapter; + } + qDebug() << "pairingStatus = " << static_cast<int>(pairingStatus); + emit pairingFinished(qTBTDevAddrToQBluetoothAddress(aAddr),pairingStatus); + } + break; + case BTKErrRemoteDeviceIndicatedNoBonding: + m_pairingErrorString.append("Dedicated bonding attempt failure when the remote device responds with No-Bonding"); + break; + default: + m_pairingErrorString.append("Symbian pairing error=") + aErr; + break; + } + if (aErr != KErrNone) + emit pairingError(aErr); + +} + +#include "moc_bluetoothsymbianpairingadapter.cpp" diff --git a/src/bluetooth/symbian/bluetoothsymbianpairingadapter.h b/src/bluetooth/symbian/bluetoothsymbianpairingadapter.h new file mode 100644 index 00000000..68be17d5 --- /dev/null +++ b/src/bluetooth/symbian/bluetoothsymbianpairingadapter.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BLUETOOTHSYMBIANPAIRINGADAPTER_H +#define BLUETOOTHSYMBIANPAIRINGADAPTER_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <qconnectivityglobal.h> +#include <QtCore/QObject> + +#include <e32base.h> +#include <btdevice.h> +#include <bt_sock.h> +#include <btengconnman.h> +#include "qbluetoothlocaldevice.h" + +QT_BEGIN_HEADER + +class QBluetoothAddress; + +class BluetoothSymbianPairingAdapter : public QObject, public MBTEngConnObserver +{ + Q_OBJECT +public: + + explicit BluetoothSymbianPairingAdapter(const QBluetoothAddress &address, QObject *parent = 0); + ~BluetoothSymbianPairingAdapter(); + + void startPairing(QBluetoothLocalDevice::Pairing pairing); + + int errorCode() const; + QString pairingErrorString() const; + +public: //from MBTEngConnObserver + virtual void ConnectComplete( TBTDevAddr& aAddr, TInt aErr, + RBTDevAddrArray* aConflicts = NULL ); + virtual void DisconnectComplete( TBTDevAddr& aAddr, TInt aErr ); + + virtual void PairingComplete( TBTDevAddr& aAddr, TInt aErr ); + +Q_SIGNALS: // SIGNALS + void pairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing); + void pairingDisplayPinCode(const QBluetoothAddress &address, QString pin); + void pairingError(int errorCode); +private: + + // socket server handle + CBTEngConnMan *m_pairingEngine; + const QBluetoothAddress &m_address; + bool m_pairingOngoing; + int m_errorCode; + QString m_pairingErrorString; +}; + +QT_END_HEADER + +#endif //BLUETOOTHSYMBIANPAIRINGADAPTER_H diff --git a/src/bluetooth/symbian/bluetoothsymbianregistryadapter.cpp b/src/bluetooth/symbian/bluetoothsymbianregistryadapter.cpp new file mode 100644 index 00000000..4652cb42 --- /dev/null +++ b/src/bluetooth/symbian/bluetoothsymbianregistryadapter.cpp @@ -0,0 +1,200 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// INCLUDE FILES +#include "bluetoothsymbianregistryadapter.h" +#include "qbluetoothaddress.h" +#include "qbluetoothdeviceinfo.h" +#include <qstring.h> +#include <btdevice.h> +#include "utils_symbian_p.h" + +/*! \internal + \class BluetoothSymbianRegistryAdapter + \brief The BluetoothSymbianRegistryAdapter class is an adapter for handling Symbian Bluetooth + Registry. + + The BluetoothSymbianRegistryAdapter is constructed to use for a one QBluetoothAddress. + It uses following Symbian class CBTEngDevMan for native operations. + + \ingroup connectivity-bluetooth + \inmodule QtConnectivity + \internal + + @internalComponent + +*/ + +BluetoothSymbianRegistryAdapter::BluetoothSymbianRegistryAdapter(const QBluetoothAddress &address, QObject *parent) + : QObject(parent) + , m_bluetoothDeviceManager(0) + , m_address(address) + , m_operation(NoOp) +{ + TRAP(m_errorCode, m_bluetoothDeviceManager = CBTEngDevMan::NewL(this)) + if (m_errorCode != KErrNone) + emit registryHandlingError(m_errorCode); +} +BluetoothSymbianRegistryAdapter::~BluetoothSymbianRegistryAdapter() +{ + delete m_bluetoothDeviceManager; +} + +int BluetoothSymbianRegistryAdapter::errorCode() const +{ + return m_errorCode; +} + +QString BluetoothSymbianRegistryAdapter::pairingErrorString() const +{ + return m_pairingErrorString; +} + +QBluetoothLocalDevice::Pairing BluetoothSymbianRegistryAdapter::remoteDevicePairingStatus() +{ + QBluetoothLocalDevice::Pairing returnValue = QBluetoothLocalDevice::Unpaired; + // if the address provided is not valid + if (m_address.isNull()) { + emit registryHandlingError((int)KErrArgument); + return returnValue; + } + int errorCode = 0; + // use Symbian registry to get a current pairing status of a device + // do not pass observer for this method -> use sync version of GetDevices() + CBTEngDevMan *btDeviceManager = NULL; + TRAPD(deviceManagerCreationErr, btDeviceManager = CBTEngDevMan::NewL(NULL)); + if (deviceManagerCreationErr != KErrNone) { + emit registryHandlingError((int)deviceManagerCreationErr); + return returnValue; + } + + // Spesify search criteria + TBTRegistrySearch lSearchCriteria; + TBTDevAddr btAddress(m_address.toUInt64()); + lSearchCriteria.FindAddress(btAddress); + + CBTDeviceArray *listOfDevices = NULL; + TRAPD(arrayCreationErr,listOfDevices = createDeviceArrayL()); + if (arrayCreationErr !=KErrNone) { + emit registryHandlingError((int)arrayCreationErr); + // cleanup manager before returning + delete btDeviceManager; + return returnValue; + } + errorCode = btDeviceManager->GetDevices(lSearchCriteria,listOfDevices); + if (errorCode != KErrNone) { + emit registryHandlingError(errorCode); + return returnValue; + } + if ( listOfDevices->Count() == 1) { + CBTDevice *device= listOfDevices->At(0); + bool isValidDevicePaired = device->IsValidPaired(); + bool isDevicePaired = device->IsPaired(); + //TODO Check whether check is correct? + if (isValidDevicePaired || isDevicePaired) { + if (device->GlobalSecurity().NoAuthorise()) + returnValue = QBluetoothLocalDevice::AuthorizedPaired; + else + returnValue = QBluetoothLocalDevice::Paired; + } + else if (!isValidDevicePaired && !isDevicePaired) { + returnValue = QBluetoothLocalDevice::Unpaired; + } + + } else { + returnValue = QBluetoothLocalDevice::Unpaired; + } + //cleanup + listOfDevices->ResetAndDestroy(); + delete listOfDevices; + delete btDeviceManager; + return returnValue; +} +CBTDeviceArray* BluetoothSymbianRegistryAdapter::createDeviceArrayL() const +{ + return q_check_ptr(new CBTDeviceArray(10)); +} + +void BluetoothSymbianRegistryAdapter::removePairing() +{ + // setup current values + int errorCode = 0; + m_operation = RemovePairing; + // Spesify search criteria + TBTRegistrySearch searchCriteria; + TBTDevAddr btAddress(m_address.toUInt64()); + searchCriteria.FindAddress(btAddress); + errorCode = m_bluetoothDeviceManager->DeleteDevices(searchCriteria); + // if there is error then manually call callback for error routines + if (errorCode != KErrNone) + HandleDevManComplete(errorCode); + +} + +QBluetoothLocalDevice::Pairing BluetoothSymbianRegistryAdapter::pairingStatus() +{ + m_operation = PairingStatus; // only needed for uniformity + QBluetoothLocalDevice::Pairing pairStatus = remoteDevicePairingStatus(); + m_operation = NoOp; + + return pairStatus; +} + +void BluetoothSymbianRegistryAdapter::HandleDevManComplete( TInt aErr ) +{ + m_errorCode = aErr; + if (aErr != KErrNone) { + emit registryHandlingError(aErr); + } + if (m_operation == RemovePairing) { + emit pairingStatusChanged(m_address, QBluetoothLocalDevice::Unpaired); + m_operation = NoOp; + } + +} + +void BluetoothSymbianRegistryAdapter::HandleGetDevicesComplete( TInt aErr,CBTDeviceArray* aDeviceArray ) +{ + Q_UNUSED(aErr); + Q_UNUSED(aDeviceArray); +} + +#include "moc_bluetoothsymbianregistryadapter.cpp" diff --git a/src/bluetooth/symbian/bluetoothsymbianregistryadapter.h b/src/bluetooth/symbian/bluetoothsymbianregistryadapter.h new file mode 100644 index 00000000..9733533d --- /dev/null +++ b/src/bluetooth/symbian/bluetoothsymbianregistryadapter.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BLUETOOTHSYMBIANREGISTRYADAPTER_H +#define BLUETOOTHSYMBIANREGISTRYADAPTER_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <qconnectivityglobal.h> +#include <QtCore/QObject> + +#include <e32base.h> +#include <btdevice.h> +#include <bt_sock.h> +#include <btengdevman.h> +#include "qbluetoothlocaldevice.h" + +QT_BEGIN_HEADER + +class QBluetoothDeviceInfo; +class QBluetoothAddress; + +class BluetoothSymbianRegistryAdapter : public QObject, public MBTEngDevManObserver +{ + Q_OBJECT +public: + + explicit BluetoothSymbianRegistryAdapter(const QBluetoothAddress &address, QObject *parent = 0); + ~BluetoothSymbianRegistryAdapter(); + + void removePairing(); + QBluetoothLocalDevice::Pairing pairingStatus(); + int errorCode() const; + QString pairingErrorString() const; + +public: //from MBTEngDevManObserver + virtual void HandleDevManComplete( TInt aErr ); + virtual void HandleGetDevicesComplete( TInt aErr,CBTDeviceArray* aDeviceArray ); + + +private: + QBluetoothLocalDevice::Pairing remoteDevicePairingStatus(); + CBTDeviceArray* createDeviceArrayL() const; + +Q_SIGNALS: // SIGNALS + void registryHandlingError(int errorCode); + void pairingStatusChanged(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing); + +private: + enum Operation { + NoOp, + PairingStatus, + RemovePairing + }; +private: + // Symbian registry hander + CBTEngDevMan *m_bluetoothDeviceManager; + const QBluetoothAddress &m_address; + Operation m_operation; + + int m_errorCode; + QString m_pairingErrorString; +}; + +QT_END_HEADER + +#endif //BLUETOOTHSYMBIANREGISTRYADAPTER_H diff --git a/src/bluetooth/symbian/symbian.pri b/src/bluetooth/symbian/symbian.pri new file mode 100644 index 00000000..d45ce209 --- /dev/null +++ b/src/bluetooth/symbian/symbian.pri @@ -0,0 +1,30 @@ + +contains(SYMBIAN_VERSION, Symbian3) { + message("Extended Inquiry Request supported") + DEFINES += EIR_SUPPORTED +} + +PRIVATE_HEADERS += \ + bluetooth/symbian/bluetoothlinkmanagerdevicediscoverer.h \ + bluetooth/symbian/utils_symbian_p.h + +SOURCES += \ + bluetooth/symbian/bluetoothlinkmanagerdevicediscoverer.cpp + +contains(btengconnman_symbian_enabled, yes) { + DEFINES += USING_BTENGCONNMAN + LIBS *=-lbtengconnman + PRIVATE_HEADERS += \ + bluetooth/symbian/bluetoothsymbianpairingadapter.h + SOURCES += \ + bluetooth/symbian/bluetoothsymbianpairingadapter.cpp +} + +contains(btengdevman_symbian_enabled, yes) { + DEFINES += USING_BTENGDEVMAN + LIBS *=-lbtengdevman + PRIVATE_HEADERS += \ + bluetooth/symbian/bluetoothsymbianregistryadapter.h + SOURCES += \ + bluetooth/symbian/bluetoothsymbianregistryadapter.cpp +} diff --git a/src/bluetooth/symbian/utils_symbian_p.h b/src/bluetooth/symbian/utils_symbian_p.h new file mode 100644 index 00000000..5f7a3dc9 --- /dev/null +++ b/src/bluetooth/symbian/utils_symbian_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef UTILS_SYMBIAN_P_H +#define UTILS_SYMBIAN_P_H + +#include <bttypes.h> +#include <bt_sock.h> + +QT_BEGIN_HEADER + +inline QBluetoothAddress qTBTDevAddrToQBluetoothAddress(const TBTDevAddr &address) +{ + return QBluetoothAddress(QString(QByteArray((const char *)address.Des().Ptr(), 6).toHex().toUpper())); +} +inline quint32 qTPackSymbianDeviceClass(const TInquirySockAddr &address) +{ + TUint8 minorClass = address.MinorClassOfDevice(); + TUint8 majorClass = address.MajorClassOfDevice(); + TUint16 serviceClass = address.MajorServiceClass(); + quint32 deviceClass = (0 << 2) | (minorClass << 6 ) | (majorClass <<5) | serviceClass; + return deviceClass; +} +inline QString s60DescToQString(const TDesC &desc) +{ + return QString::fromUtf16(desc.Ptr(), desc.Length()); +} +inline QByteArray s60Desc8ToQByteArray(const TDesC8 &desc) +{ + return QByteArray((const char*)desc.Ptr(), desc.Length()); +} + +QT_END_HEADER + +#endif |