From a45977185a485624095bff1a15024e9199eee676 Mon Sep 17 00:00:00 2001 From: Javier Date: Fri, 1 Jan 2016 22:05:42 +0100 Subject: reorganize source files into SAP and agents --- sap/sapbtlistener.cc | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 sap/sapbtlistener.cc (limited to 'sap/sapbtlistener.cc') diff --git a/sap/sapbtlistener.cc b/sap/sapbtlistener.cc new file mode 100644 index 0000000..9776b59 --- /dev/null +++ b/sap/sapbtlistener.cc @@ -0,0 +1,182 @@ +#include + +#include "saprotocol.h" +#include "sapbtlistener.h" +#include "sapbtpeer.h" + +#ifdef SAILFISH +#include +#include +#include +#include +#endif +#ifdef DESKTOP +#include "hfpag.h" +#endif + +SAPBTListener::SAPBTListener(QObject *parent) : + QObject(parent), _server(0) +{ +} + +SAPBTListener::~SAPBTListener() +{ + stop(); +} + +void SAPBTListener::start() +{ + if (_server) { + qWarning() << "Already started"; + return; + } + + _server = new QBluetoothServer(QBluetoothServiceInfo::RfcommProtocol, this); + connect(_server, SIGNAL(newConnection()), this, SLOT(acceptConnection())); + if (!_server->listen(QBluetoothAddress(), 0)) { + qWarning() << "Failed to start Bluetooth listener socket"; + stop(); + return; + } + + quint8 serverPort = _server->serverPort(); + + /* + Service Name: SAP + Service RecHandle: 0x1000b + Service Class ID List: + UUID 128: a49eb41e-cb06-495c-9f4f-bb80a90cdf00 + Protocol Descriptor List: + "L2CAP" (0x0100) + "RFCOMM" (0x0003) + Channel: 5 + + Service Name: SAP + Service RecHandle: 0x1000c + Service Class ID List: + UUID 128: a49eb41e-cb06-495c-9f4f-aa80a90cdf4a + Protocol Descriptor List: + "L2CAP" (0x0100) + "RFCOMM" (0x0003) + Channel: 6 + */ + + _service.setServiceName("SAP"); + _service.setServiceDescription("Samsung Accessory Profile"); + _service.setServiceProvider("gearbtteest"); + + QBluetoothServiceInfo::Sequence classIds; + classIds.append(QVariant::fromValue(SAProtocol::dataServiceUuid)); + _service.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classIds); + + QBluetoothServiceInfo::Sequence browseGroupList; + browseGroupList.append(QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup))); + _service.setAttribute(QBluetoothServiceInfo::BrowseGroupList, browseGroupList); + + QBluetoothServiceInfo::Sequence protocolDescriptorList; + QBluetoothServiceInfo::Sequence protocol; + + protocol.append(QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::L2cap))); + protocolDescriptorList.append(QVariant::fromValue(protocol)); + protocol.clear(); + + protocol.append(QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm))); + protocol.append(QVariant::fromValue(serverPort)); + protocolDescriptorList.append(QVariant::fromValue(protocol)); + protocol.clear(); + + _service.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, + protocolDescriptorList); + + if (!_service.registerService()) { + qWarning() << "Failed to register the SAP service"; + } +} + +void SAPBTListener::stop() +{ + if (!_server) { + return; + } + + if (!_service.unregisterService()) { + qWarning() << "Failed to unregister SAP service"; + } + + delete _server; + _server = 0; +} + +void SAPBTListener::nudge(const QBluetoothAddress &address) +{ + QBluetoothSocket *socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol, this); + + connect(socket, SIGNAL(connected()), this, SLOT(handleNudgeConnected())); + connect(socket, SIGNAL(error(QBluetoothSocket::SocketError)), + this, SLOT(handleNudgeError(QBluetoothSocket::SocketError))); + + qDebug() << "Nudging" << address.toString(); + + // First, set up HFP/Headset connection to watch +#if SAILFISH + QDBusConnection bus = QDBusConnection::systemBus(); + OrgBluezManagerInterface manager("org.bluez", "/", bus); + QDBusReply defaultAdapter = manager.DefaultAdapter(); + if (!defaultAdapter.isValid()) { + qWarning() << "Could not get default Bluez adapter:" << defaultAdapter.error().message(); + } + OrgBluezAdapterInterface adapter("org.bluez", defaultAdapter.value().path(), bus); + QList list = adapter.ListDevices(); + foreach (QDBusObjectPath item, list) { + OrgBluezDeviceInterface device("org.bluez", item.path(), bus); + QVariantMap properties = device.GetProperties(); + QBluetoothAddress devAddress(properties["Address"].toString()); + if (devAddress == address) { + OrgBluezHeadsetInterface headset("org.bluez", item.path(), bus); + qDebug() << "Creating HFP connection to" << devAddress.toString(); + headset.Connect(); + } + } +#elif DESKTOP + new HfpAg(address, this); +#endif + + // After that, start normal connection. +#if SAILFISH + // For some reason, using UUIDs here fails on SailfishOS + socket->connectToService(address, 1); +#else + socket->connectToService(address, SAProtocol::nudgeServiceUuid); +#endif +} + +void SAPBTListener::acceptConnection() +{ + qDebug() << "Incoming BT connection"; + QBluetoothSocket *socket = _server->nextPendingConnection(); + if (!socket) { + qWarning() << "Actually, no incoming connection"; + return; + } + + qDebug() << "Got connection"; + + // TODO Why am I hardcoding the role here + SAPBTPeer *peer = new SAPBTPeer(SAProtocol::ClientRole, socket, this); + connect(peer, SIGNAL(disconnected()), peer, SLOT(deleteLater())); +} + +void SAPBTListener::handleNudgeConnected() +{ + QBluetoothSocket *socket = static_cast(sender()); + qDebug() << "Nudge connected:" << socket->peerAddress().toString(); + new SAPBTPeer(SAProtocol::ClientRole, socket, this); +} + +void SAPBTListener::handleNudgeError(QBluetoothSocket::SocketError error) +{ + QBluetoothSocket *socket = static_cast(sender()); + qWarning() << "Cannot nudge:" << error << socket->errorString(); + socket->abort(); + socket->deleteLater(); +} -- cgit v1.2.3