From 3b5fc081c8d22fac73db0fbe63eb2058595d43f6 Mon Sep 17 00:00:00 2001 From: Javier Date: Sun, 29 Jun 2014 17:32:54 +0200 Subject: initial import --- bluetoothgpsserver.cpp | 137 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 bluetoothgpsserver.cpp (limited to 'bluetoothgpsserver.cpp') diff --git a/bluetoothgpsserver.cpp b/bluetoothgpsserver.cpp new file mode 100644 index 0000000..efbddf0 --- /dev/null +++ b/bluetoothgpsserver.cpp @@ -0,0 +1,137 @@ +#include + +#include "nmeasource.h" +#include "bluetoothgpsserver.h" + +BluetoothGpsServer::BluetoothGpsServer(uint port, QObject *parent) : + QObject(parent), m_port(port), m_source(new NmeaSource(this)), m_server(0) +{ + connect(m_source, SIGNAL(dataReady(QString)), this, SLOT(sendData(QString))); +} + +BluetoothGpsServer::~BluetoothGpsServer() +{ + stop(); +} + +void BluetoothGpsServer::start() +{ + if (m_server) { + return; + } + + m_server = new QRfcommServer(this); + connect(m_server, SIGNAL(newConnection()), this, SLOT(acceptConnection())); + if (!m_server->listen(QBluetoothAddress(), m_port)) { + qWarning() << "Failed to start Bluetooth listener socket"; + stop(); + return; + } + + quint8 serverPort = m_server->serverPort(); + + const QBluetoothUuid service_uuid(QLatin1String("2af0b21d-2d9d-43bd-9693-5d9235fa2033")); + const QBluetoothUuid gnss_profile_uuid(quint16(0x1135)); + const QBluetoothUuid gnss_server_uuid(quint16(0x1136)); + + m_service.setServiceName("GPS"); + m_service.setServiceDescription("GPS/NMEA emulator over Serial Port"); + m_service.setServiceProvider("btgpsd"); + m_service.setServiceUuid(service_uuid); + + QBluetoothServiceInfo::Sequence classIds; + classIds.append(QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort))); + classIds.append(QVariant::fromValue(gnss_server_uuid)); + m_service.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classIds); + + QBluetoothServiceInfo::Sequence browseGroupList; + browseGroupList.append(QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup))); + m_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(); + + m_service.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, + protocolDescriptorList); + + QBluetoothServiceInfo::Sequence profileDescriptorList; + protocol.append(QVariant::fromValue(gnss_profile_uuid)); + protocol.append(QVariant::fromValue(0x100)); + profileDescriptorList.append(QVariant::fromValue(protocol)); + protocol.clear(); + + // Profile Descriptor list + m_service.setAttribute(0x0009, QVariant::fromValue(profileDescriptorList)); + + if (!m_service.registerService()) { + qWarning() << "Failed to register the Serial Port service"; + } +} + +void BluetoothGpsServer::stop() +{ + if (!m_server) { + return; + } + + if (!m_service.unregisterService()) { + qWarning() << "Failed to unregister Serial Port service"; + } + + qDeleteAll(m_clients); + m_clients.clear(); + m_source->stop(); + + delete m_server; + m_server = 0; +} + +void BluetoothGpsServer::sendData(const QString &data) +{ + QByteArray text = data.toLatin1(); + foreach (QBluetoothSocket *socket, m_clients) { + socket->write(text); + } +} + +void BluetoothGpsServer::acceptConnection() +{ + qDebug() << "Incoming BT connection"; + QBluetoothSocket *socket = m_server->nextPendingConnection(); + if (!socket) { + qWarning() << "Actually, no incoming connection"; + return; + } + + connect(socket, SIGNAL(disconnected()), this, SLOT(handleDisconnection())); + + m_clients.append(socket); + if (m_clients.size() == 1) { + // This was the first client; start listening to GPS + qDebug() << "Starting GPS for BT"; + m_source->start(); + } +} + +void BluetoothGpsServer::handleDisconnection() +{ + QBluetoothSocket *socket = qobject_cast(sender()); + Q_ASSERT(socket); + + m_clients.removeOne(socket); + socket->deleteLater(); + + if (m_clients.isEmpty()) { + qDebug() << "Stopping GPS for BT"; + m_source->stop(); + } +} -- cgit v1.2.3