From 0e7b5c4922bbcb5cf0e3a85a6dd1ba4b82b2097e Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Fri, 26 Jul 2013 14:02:44 +0200 Subject: QNX: Fake rfcomm ports We need a way to associate a service with a server. The current API does that using rfcomm ports. On QNX We do not have access to the rfcomm ports, so we fake the behavior. Change-Id: I893fd60dc4cbc515643fe8218532de6634a6d88e Reviewed-by: Alex --- src/bluetooth/qbluetoothserviceinfo_qnx.cpp | 24 +++++++---- src/bluetooth/qnx/ppshelpers.cpp | 21 ++++----- src/bluetooth/qrfcommserver_qnx.cpp | 66 +++++++++++++++++++---------- 3 files changed, 67 insertions(+), 44 deletions(-) (limited to 'src/bluetooth') diff --git a/src/bluetooth/qbluetoothserviceinfo_qnx.cpp b/src/bluetooth/qbluetoothserviceinfo_qnx.cpp index 3765887a..691c3a0c 100644 --- a/src/bluetooth/qbluetoothserviceinfo_qnx.cpp +++ b/src/bluetooth/qbluetoothserviceinfo_qnx.cpp @@ -85,6 +85,8 @@ void QBluetoothServiceInfoPrivate::removeRegisteredAttribute(quint16 attributeId registered = false; } +extern QHash __fakeServerPorts; + bool QBluetoothServiceInfoPrivate::registerService() const { Q_Q(const QBluetoothServiceInfo); @@ -92,15 +94,19 @@ bool QBluetoothServiceInfoPrivate::registerService() const qWarning() << Q_FUNC_INFO << "Only SPP services can be registered on QNX"; return false; } - ppsRegisterControl(); - //if (registered) - // ppsSendControlMessage("deregister_server", 0x1101, q->serviceUuid(), QString(), 0); - - //If any server instance is already running, it is deregistered - qBBBluetoothDebug() << "deregistering server"; - ppsSendControlMessage("deregister_server", 0x1101, q->serviceUuid(), QString(), 0); - qBBBluetoothDebug() << "registering spp server: UUID" << q->serviceUuid(); - ppsSendControlMessage("register_server", 0x1101, q->serviceUuid(), q->serviceName(), 0); + + if (q->serverChannel() == -1) + return false; + + if (__fakeServerPorts.key(q->serverChannel()) != 0) { + qBBBluetoothDebug() << "Registering server with UUID" << + q->serviceUuid() << " Name" << q->serviceName(); + qDebug() << "Server is" << __fakeServerPorts.key(q->serverChannel()); + ppsSendControlMessage("register_server", 0x1101, q->serviceUuid(), q->serviceName(), + __fakeServerPorts.key(q->serverChannel()), BT_SPP_SERVER_SUBTYPE); + } else { + return false; + } registered = true; return true; diff --git a/src/bluetooth/qnx/ppshelpers.cpp b/src/bluetooth/qnx/ppshelpers.cpp index cb40ce06..f9bbd03a 100644 --- a/src/bluetooth/qnx/ppshelpers.cpp +++ b/src/bluetooth/qnx/ppshelpers.cpp @@ -42,6 +42,7 @@ #include "ppshelpers_p.h" #include #include +#include "../qrfcommserver_p.h" QT_BEGIN_NAMESPACE_BLUETOOTH @@ -59,6 +60,8 @@ static const int ppsBufferSize = 1024; static int ctrlId = 20; +QHash __fakeServerPorts; + QList > evtRegistration; void BBSocketNotifier::distribute() @@ -141,10 +144,12 @@ void ppsSendControlMessage(const char *msg, int service, const QBluetoothUuid &u pps_encoder_add_string(encoder, "uuid", uuid.toString().mid(1,36).toUtf8().constData()); - if (QByteArray(msg) == QByteArray("register_server")) - pps_encoder_add_string(encoder, "name", address.toUtf8().constData()); - else if (!address.isEmpty()) + if (QByteArray(msg) == QByteArray("register_server")) { + if (!address.isEmpty()) + pps_encoder_add_string(encoder, "name", address.toUtf8().constData()); + } else if (!address.isEmpty()) { pps_encoder_add_string(encoder, "addr", address.toUtf8().constData()); + } pps_encoder_error_t rese = pps_encoder_end_object(encoder); @@ -159,16 +164,6 @@ void ppsSendControlMessage(const char *msg, int service, const QBluetoothUuid &u void ppsSendControlMessage(const char *msg, const QString &dat, QObject *sender) { pps_encoder_t *encoder = beginCtrlMessage(msg, sender); - -// pps_encoder_t json_encoder; -// pps_encoder_initialize( &json_encoder, true); -// pps_encoder_reset( &json_encoder ); -// pps_encoder_start_object( &json_encoder, NULL); -// if ( pps_encoder_add_int( &json_encoder, "access", 1 ) == PPS_ENCODER_OK ) { -// pps_encoder_end_object( &json_encoder ); -// pps_encoder_add_json(encoder, "dat", pps_encoder_buffer( &json_encoder ) ); -// } -// pps_encoder_cleanup( &json_encoder ); pps_encoder_add_json(encoder, "dat", dat.toUtf8().constData()); endCtrlMessage(encoder); } diff --git a/src/bluetooth/qrfcommserver_qnx.cpp b/src/bluetooth/qrfcommserver_qnx.cpp index 514a0a3d..eecc0e94 100644 --- a/src/bluetooth/qrfcommserver_qnx.cpp +++ b/src/bluetooth/qrfcommserver_qnx.cpp @@ -51,16 +51,22 @@ QT_BEGIN_NAMESPACE_BLUETOOTH +extern QHash __fakeServerPorts; + QRfcommServerPrivate::QRfcommServerPrivate() : socket(0),maxPendingConnections(1),securityFlags(QBluetooth::NoSecurity) { + socket = new QBluetoothSocket(QBluetoothSocket::RfcommSocket); ppsRegisterControl(); } QRfcommServerPrivate::~QRfcommServerPrivate() { + Q_Q(QRfcommServer); if (socket) delete socket; + q->close(); + __fakeServerPorts.remove(this); ppsUnregisterControl(this); } @@ -76,13 +82,14 @@ void QRfcommServerPrivate::controlReply(ppsResult result) int socketFD = ::open(result.dat.first().toStdString().c_str(), O_RDWR | O_NONBLOCK); if (socketFD == -1) { - qWarning() << Q_FUNC_INFO << "RFCOMM Server: Could not open socket FD"; + qWarning() << Q_FUNC_INFO << "RFCOMM Server: Could not open socket FD" << errno; } else { - QBluetoothSocket *newSocket = new QBluetoothSocket; - newSocket->setSocketDescriptor(socketFD, QBluetoothSocket::RfcommSocket, + socket->setSocketDescriptor(socketFD, QBluetoothSocket::RfcommSocket, QBluetoothSocket::ConnectedState); - newSocket->connectToService(QBluetoothAddress(nextClientAddress), m_uuid); - activeSockets.append(newSocket); + socket->connectToService(QBluetoothAddress(nextClientAddress), m_uuid); + activeSockets.append(socket); + socket = new QBluetoothSocket(QBluetoothSocket::RfcommSocket, this); + socket->setSocketState(QBluetoothSocket::ListeningState); emit q->newConnection(); } } @@ -97,10 +104,11 @@ void QRfcommServerPrivate::controlEvent(ppsResult result) qBBBluetoothDebug() << result.dat.at(i); } - if (result.dat.contains("addr") && result.dat.contains("uuid") && result.dat.contains("subtype")) { - nextClientAddress = result.dat.at(result.dat.indexOf("addr") + 1); - m_uuid = QBluetoothUuid(result.dat.at(result.dat.indexOf("uuid") + 1)); - int subtype = result.dat.at(result.dat.indexOf("subtype") + 1).toInt(); + if (result.dat.contains("addr") && result.dat.contains(QStringLiteral("uuid")) + && result.dat.contains(QStringLiteral("subtype"))) { + nextClientAddress = result.dat.at(result.dat.indexOf(QStringLiteral("addr")) + 1); + m_uuid = QBluetoothUuid(result.dat.at(result.dat.indexOf(QStringLiteral("uuid")) + 1)); + int subtype = result.dat.at(result.dat.indexOf(QStringLiteral("subtype")) + 1).toInt(); qBBBluetoothDebug() << "Getting mount point path" << m_uuid << nextClientAddress<< subtype; ppsSendControlMessage("get_mount_point_path", 0x1101, m_uuid, nextClientAddress, this, BT_SPP_SERVER_SUBTYPE); } else { @@ -118,23 +126,41 @@ void QRfcommServer::close() return; } d->socket->close(); + d->socket = 0; + ppsSendControlMessage("deregister_server", 0x1101, d->m_uuid, QString(), 0); // force active object (socket) to run and shutdown socket. qApp->processEvents(QEventLoop::ExcludeUserInputEvents); } bool QRfcommServer::listen(const QBluetoothAddress &address, quint16 port) { - Q_UNUSED(port) Q_UNUSED(address) Q_D(QRfcommServer); // listen has already been called before - if (d->socket) + if (d->socket->state() == QBluetoothSocket::ListeningState) return true; - d->socket = new QBluetoothSocket(QBluetoothSocket::RfcommSocket, this); + //We can not register an actual Rfcomm port, because the platform does not allow it + //but we need a way to associate a server with a service + + if (port == 0) { //Try to assign a non taken port id + for (int i=1; ; i++){ + if (__fakeServerPorts.key(i) == 0) { + port = i; + break; + } + } + } - if (!d->socket) + if (port>=0 && __fakeServerPorts.key(port) == 0) { + __fakeServerPorts[d] = port; + qBBBluetoothDebug() << "Port" << port << "registered"; + } else { + qWarning() << "server with port" << port << "already registered or port invalid"; return false; + } + + d->socket->setSocketState(QBluetoothSocket::ListeningState); ppsRegisterForEvent(QStringLiteral("service_connected"),d); return true; @@ -143,7 +169,7 @@ bool QRfcommServer::listen(const QBluetoothAddress &address, quint16 port) void QRfcommServer::setMaxPendingConnections(int numConnections) { Q_D(QRfcommServer); - d->maxPendingConnections = numConnections; + d->maxPendingConnections = numConnections; //Currently not used } QBluetoothAddress QRfcommServer::serverAddress() const @@ -159,10 +185,7 @@ quint16 QRfcommServer::serverPort() const { //Currently we do not have access to the port Q_D(const QRfcommServer); - if (d->socket) - return d->socket->localPort(); - else - return 0; + return __fakeServerPorts.value((QRfcommServerPrivate*)d); } bool QRfcommServer::hasPendingConnections() const @@ -177,20 +200,19 @@ QBluetoothSocket *QRfcommServer::nextPendingConnection() if (d->activeSockets.isEmpty()) return 0; - QBluetoothSocket *next = d->activeSockets.takeFirst(); - return next; + return d->activeSockets.takeFirst(); } void QRfcommServer::setSecurityFlags(QBluetooth::SecurityFlags security) { Q_D(QRfcommServer); - d->securityFlags = security; + d->securityFlags = security; //not used } QBluetooth::SecurityFlags QRfcommServer::securityFlags() const { Q_D(const QRfcommServer); - return d->securityFlags; + return d->securityFlags; //not used } QT_END_NAMESPACE_BLUETOOTH -- cgit v1.2.3