From 4c301dfa6b4193115b6cf56ba0206a45d3a43977 Mon Sep 17 00:00:00 2001 From: Nedim Hadzic Date: Thu, 17 Apr 2014 17:39:34 +0200 Subject: BlackBerry C API added for OS>10.2.1 With new OS 10.3 some PPS object paths are changed. Therefore BB C API was used intead of PPS communication in some parts of QtConnectivity. The BB C API is introduced for OS 10.2.1 and newer. Change-Id: I94a21ed61a49a94dd2101990df4801a6925a3ce6 Reviewed-by: Alex Blasche Reviewed-by: Fabian Bumberger --- src/bluetooth/qbluetoothserver_p.h | 6 +++ src/bluetooth/qbluetoothserver_qnx.cpp | 59 +++++++++++++++++++--- src/bluetooth/qbluetoothserviceinfo_qnx.cpp | 31 ++++++++++++ src/bluetooth/qbluetoothsocket_qnx.cpp | 77 ++++++++++++++++++++++++----- 4 files changed, 154 insertions(+), 19 deletions(-) diff --git a/src/bluetooth/qbluetoothserver_p.h b/src/bluetooth/qbluetoothserver_p.h index 4137986a..afd9d50f 100644 --- a/src/bluetooth/qbluetoothserver_p.h +++ b/src/bluetooth/qbluetoothserver_p.h @@ -97,6 +97,10 @@ public: QBluetoothServiceInfo::Protocol serverType; #ifdef QT_QNX_BLUETOOTH +#ifdef QT_QNX_BT_BLUETOOTH + static void btCallback(long param, int socket); + Q_INVOKABLE void setBtCallbackParameters(int receivedSocket); +#endif QList activeSockets; QString m_serviceName; #endif @@ -112,8 +116,10 @@ private: QString nextClientAddress; private Q_SLOTS: +#ifndef QT_QNX_BT_BLUETOOTH void controlReply(ppsResult result); void controlEvent(ppsResult result); +#endif #elif defined(QT_BLUEZ_BLUETOOTH) QSocketNotifier *socketNotifier; #elif defined(QT_ANDROID_BLUETOOTH) diff --git a/src/bluetooth/qbluetoothserver_qnx.cpp b/src/bluetooth/qbluetoothserver_qnx.cpp index cc28296c..2aefa041 100644 --- a/src/bluetooth/qbluetoothserver_qnx.cpp +++ b/src/bluetooth/qbluetoothserver_qnx.cpp @@ -48,7 +48,9 @@ #include #include - +#ifdef QT_QNX_BT_BLUETOOTH +#include +#endif QT_BEGIN_NAMESPACE extern QHash __fakeServerPorts; @@ -70,6 +72,42 @@ QBluetoothServerPrivate::~QBluetoothServerPrivate() activeSockets.clear(); } +#ifdef QT_QNX_BT_BLUETOOTH +void QBluetoothServerPrivate::btCallback(long param, int socket) +{ + QBluetoothServerPrivate *impl = reinterpret_cast(param); + QMetaObject::invokeMethod(impl, "setBtCallbackParameters", + Qt::BlockingQueuedConnection, + Q_ARG(int, socket)); +} + +void QBluetoothServerPrivate::setBtCallbackParameters(int receivedSocket) +{ + Q_Q(QBluetoothServer); + if (receivedSocket == -1) { + qCDebug(QT_BT_QNX) << "Socket error: " << qt_error_string(errno); + m_lastError = QBluetoothServer::InputOutputError; + emit q->error(m_lastError); + return; + } + socket->setSocketDescriptor(receivedSocket, QBluetoothServiceInfo::RfcommProtocol, + QBluetoothSocket::ConnectedState, + QBluetoothSocket::ReadWrite); + char addr[18]; + if (bt_spp_get_address(receivedSocket, addr) == -1) { + qCDebug(QT_BT_QNX) << "Could not obtain the remote address. " + << qt_error_string(errno); + m_lastError = QBluetoothServer::InputOutputError; + emit q->error(m_lastError); + return; + } + socket->d_ptr->m_peerAddress = QBluetoothAddress(addr); + activeSockets.append(socket); + socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol, this); + socket->setSocketState(QBluetoothSocket::ListeningState); + emit q->newConnection(); +} +#else void QBluetoothServerPrivate::controlReply(ppsResult result) { Q_Q(QBluetoothServer); @@ -130,6 +168,7 @@ void QBluetoothServerPrivate::controlEvent(ppsResult result) } } } +#endif void QBluetoothServer::close() { @@ -142,12 +181,19 @@ void QBluetoothServer::close() } if (d->socket) { d->socket->close(); - delete d->socket; - d->socket = 0; if (__fakeServerPorts.contains(d)) { - ppsSendControlMessage("deregister_server", 0x1101, d->m_uuid, QString(), QString(), 0); +#ifdef QT_QNX_BT_BLUETOOTH + QByteArray b_uuid = d->m_uuid.toByteArray(); + b_uuid = b_uuid.mid(1, b_uuid.length()-2); + bt_spp_close_server(b_uuid.data()); +#else + ppsSendControlMessage("deregister_server", 0x1101, d->m_uuid, + QString(), QString(), 0); +#endif __fakeServerPorts.remove(d); } + delete d->socket; + d->socket = 0; } } @@ -206,9 +252,10 @@ bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port) return false; } - d->socket->setSocketState(QBluetoothSocket::ListeningState); - +#ifndef QT_QNX_BT_BLUETOOTH ppsRegisterForEvent(QStringLiteral("service_connected"),d); +#endif + d->socket->setSocketState(QBluetoothSocket::ListeningState); return true; } diff --git a/src/bluetooth/qbluetoothserviceinfo_qnx.cpp b/src/bluetooth/qbluetoothserviceinfo_qnx.cpp index 30dac958..8767889b 100644 --- a/src/bluetooth/qbluetoothserviceinfo_qnx.cpp +++ b/src/bluetooth/qbluetoothserviceinfo_qnx.cpp @@ -45,6 +45,11 @@ #include "qbluetoothserver_p.h" #include "qbluetoothserver.h" +#ifdef QT_QNX_BT_BLUETOOTH +#include +#include +#endif + QT_BEGIN_NAMESPACE QBluetoothServiceInfoPrivate::QBluetoothServiceInfoPrivate() @@ -70,11 +75,19 @@ bool QBluetoothServiceInfoPrivate::unregisterService() if (serverChannel() == -1) return false; if ( __fakeServerPorts.key(serverChannel()) != 0) { +#ifdef QT_QNX_BT_BLUETOOTH + QByteArray b_uuid = attributes.value(QBluetoothServiceInfo::ServiceId). + value().toByteArray(); + b_uuid = b_uuid.mid(1, b_uuid.length() - 2); + if (bt_spp_close_server(b_uuid.data()) == -1) + return false; +#else if (!ppsSendControlMessage("deregister_server", 0x1101, attributes.value(QBluetoothServiceInfo::ServiceId).value(), QString(), attributes.value(QBluetoothServiceInfo::ServiceName).toString(), __fakeServerPorts.key(serverChannel()), BT_SPP_SERVER_SUBTYPE)) { return false; } +#endif else { __fakeServerPorts.remove(__fakeServerPorts.key(serverChannel())); registered = false; @@ -98,10 +111,28 @@ bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress& loca return false; if (__fakeServerPorts.key(serverChannel()) != 0) { +#ifdef QT_QNX_BT_BLUETOOTH + QByteArray b_uuid = attributes.value(QBluetoothServiceInfo::ServiceId) + .value().toByteArray(); + b_uuid = b_uuid.mid(1, b_uuid.length() - 2); + qCDebug(QT_BT_QNX) << "Registering server. " << b_uuid.data() + << attributes.value(QBluetoothServiceInfo::ServiceName) + .toString(); + if (bt_spp_open_server(attributes.value(QBluetoothServiceInfo::ServiceName) + .toString().toUtf8().data(), + b_uuid.data(), true, &QBluetoothServerPrivate::btCallback, + reinterpret_cast(__fakeServerPorts.key(serverChannel()))) == -1) { + qCDebug(QT_BT_QNX) << "Could not open the server. " + << qt_error_string(errno) << errno; + bt_spp_close_server(b_uuid.data()); + return false; + } +#else if (!ppsSendControlMessage("register_server", 0x1101, attributes.value(QBluetoothServiceInfo::ServiceId).value(), QString(), attributes.value(QBluetoothServiceInfo::ServiceName).toString(), __fakeServerPorts.key(serverChannel()), BT_SPP_SERVER_SUBTYPE)) return false; +#endif //The server needs to know the service name for the socket mount point path __fakeServerPorts.key(serverChannel())->m_serviceName = attributes.value(QBluetoothServiceInfo::ServiceName).toString(); } else { diff --git a/src/bluetooth/qbluetoothsocket_qnx.cpp b/src/bluetooth/qbluetoothsocket_qnx.cpp index 4deb4f84..c54a0937 100644 --- a/src/bluetooth/qbluetoothsocket_qnx.cpp +++ b/src/bluetooth/qbluetoothsocket_qnx.cpp @@ -43,8 +43,15 @@ #include "qbluetoothsocket_p.h" #include "qbluetoothlocaldevice.h" #include +#ifdef QT_QNX_BT_BLUETOOTH +#include +#include +#endif QT_BEGIN_NAMESPACE +#ifdef QT_QNX_BT_BLUETOOTH +static int initCounter = 0; +#endif QBluetoothSocketPrivate::QBluetoothSocketPrivate() : socket(-1), @@ -57,12 +64,28 @@ QBluetoothSocketPrivate::QBluetoothSocketPrivate() discoveryAgent(0), isServerSocket(false) { +#ifdef QT_QNX_BT_BLUETOOTH + if (!initCounter && (bt_spp_init() == -1)) + qCDebug(QT_BT_QNX) << "Could not initialize Bluetooth library. " + << qt_error_string(errno); + + initCounter++; +#else ppsRegisterControl(); +#endif } QBluetoothSocketPrivate::~QBluetoothSocketPrivate() { +#ifdef QT_QNX_BT_BLUETOOTH + if (initCounter == 1 && (bt_spp_deinit() == -1)) + qCDebug(QT_BT_QNX) << "Could not deinitialize Bluetooth library." + "SPP connection is still open."; + + initCounter--; +#else ppsUnregisterControl(this); +#endif close(); } @@ -79,27 +102,47 @@ void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address, const QBluetoothUuid &uuid, QIODevice::OpenMode openMode) { + Q_Q(QBluetoothSocket); Q_UNUSED(openMode); qCDebug(QT_BT_QNX) << "Connecting socket"; - if (isServerSocket) { - m_peerAddress = address; - m_uuid = uuid; + + m_peerAddress = address; +#ifdef QT_QNX_BT_BLUETOOTH + QByteArray b_uuid = uuid.toByteArray(); + b_uuid = b_uuid.mid(1, b_uuid.length() - 2); + socket = bt_spp_open(address.toString().toUtf8().data(), b_uuid.data(), false); + if (socket == -1) { + qCWarning(QT_BT_QNX) << "Could not connect to" << address.toString() << b_uuid << qt_error_string(errno); + errorString = qt_error_string(errno); + q->setSocketError(QBluetoothSocket::NetworkError); return; } + delete readNotifier; + delete connectWriteNotifier; + + 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())); + + connecting = true; + q->setOpenMode(openMode); +#else + m_uuid = uuid; + if (isServerSocket) + return; + if (state != QBluetoothSocket::UnconnectedState) { qCDebug(QT_BT_QNX) << "Socket already connected"; return; } - state = QBluetoothSocket::ConnectingState; - - m_uuid = uuid; - m_peerAddress = address; ppsSendControlMessage("connect_service", 0x1101, uuid, address.toString(), QString(), this, BT_SPP_CLIENT_SUBTYPE); ppsRegisterForEvent(QStringLiteral("service_connected"),this); ppsRegisterForEvent(QStringLiteral("get_mount_point_path"),this); - socketType = QBluetoothServiceInfo::RfcommProtocol; +#endif + q->setSocketState(QBluetoothSocket::ConnectingState); } void QBluetoothSocketPrivate::_q_writeNotify() @@ -166,9 +209,16 @@ void QBluetoothSocketPrivate::abort() { Q_Q(QBluetoothSocket); qCDebug(QT_BT_QNX) << "Disconnecting service"; +#ifdef QT_QNX_BT_BLUETOOTH + if (isServerSocket) + bt_spp_close_server(m_uuid.toString().toUtf8().data()); + else + bt_spp_close(socket); +#else if (q->state() != QBluetoothSocket::ClosingState) ppsSendControlMessage("disconnect_service", 0x1101, m_uuid, m_peerAddress.toString(), QString(), 0, isServerSocket ? BT_SPP_SERVER_SUBTYPE : BT_SPP_CLIENT_SUBTYPE); +#endif delete readNotifier; readNotifier = 0; delete connectWriteNotifier; @@ -282,11 +332,6 @@ bool QBluetoothSocketPrivate::setSocketDescriptor(int socketDescriptor, QBluetoo socket = socketDescriptor; socketType = socketType_; - // 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); @@ -299,7 +344,9 @@ bool QBluetoothSocketPrivate::setSocketDescriptor(int socketDescriptor, QBluetoo emit q->connected(); isServerSocket = true; +#ifndef QT_QNX_BT_BLUETOOTH ppsRegisterForEvent(QStringLiteral("service_disconnected"),this); +#endif return true; } @@ -311,6 +358,7 @@ qint64 QBluetoothSocketPrivate::bytesAvailable() const void QBluetoothSocketPrivate::controlReply(ppsResult result) { +#ifndef QT_QNX_BT_BLUETOOTH Q_Q(QBluetoothSocket); if (result.msg == QStringLiteral("connect_service")) { @@ -361,15 +409,18 @@ void QBluetoothSocketPrivate::controlReply(ppsResult result) ppsRegisterForEvent(QStringLiteral("service_disconnected"),this); } } +#endif } void QBluetoothSocketPrivate::controlEvent(ppsResult result) { +#ifndef QT_QNX_BT_BLUETOOTH Q_Q(QBluetoothSocket); if (result.msg == QStringLiteral("service_disconnected")) { q->setSocketState(QBluetoothSocket::ClosingState); close(); } +#endif } QT_END_NAMESPACE -- cgit v1.2.3