void QBluetoothLocalDevicePrivate::requestPairing(const QBluetoothAddress &address,
                                                  QBluetoothLocalDevice::Pairing pairing)
{
    if (pairing == QBluetoothLocalDevice::Paired
        || pairing == QBluetoothLocalDevice::AuthorizedPaired) {
        ppsSendControlMessage("initiate_pairing",
                              QStringLiteral("{\"addr\":\"%1\"}").arg(address.toString()),
                              this);
    } else {
        ppsSendControlMessage("remove_device",
                              QStringLiteral("{\"addr\":\"%1\"}").arg(address.toString()),
                              this);
    }
}
Example #2
0
void QBluetoothServer::close()
{
    Q_D(QBluetoothServer);
    if (!d->activeSockets.isEmpty()) {
        for (int i = 0; i < d->activeSockets.size(); i++)
            d->activeSockets.at(i)->close();
        qDeleteAll(d->activeSockets);
        d->activeSockets.clear();
    }
    if (d->socket) {
        d->socket->close();
        if (__fakeServerPorts.contains(d)) {
#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;
    }
}
void QBluetoothLocalDevicePrivate::setAccess(int access)
{
    if (!ppsReadSetting("enabled").toBool())   // We cannot set the host mode until BT is fully powered up
        __newHostMode = access;
    else
        ppsSendControlMessage("set_access", QStringLiteral("{\"access\":%1}").arg(access), 0);
}
void QBluetoothServerPrivate::controlEvent(ppsResult result)
{
    Q_Q(QBluetoothServer);
    if (result.msg == QStringLiteral("service_connected")) {
        qCDebug(QT_BT_QNX) << "SPP: Server: Sending request for mount point path";
        qCDebug(QT_BT_QNX) << result.dat;
        for (int i=0; i<result.dat.size(); i++) {
            qCDebug(QT_BT_QNX) << result.dat.at(i);
        }

        if (result.dat.contains(QStringLiteral("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();
            qCDebug(QT_BT_QNX) << "Getting mount point path" << m_uuid << nextClientAddress<< subtype;
            ppsSendControlMessage("get_mount_point_path", 0x1101, m_uuid, nextClientAddress,
                                  m_serviceName, this, BT_SPP_SERVER_SUBTYPE);
        } else {
            m_lastError = QBluetoothServer::InputOutputError;
            emit q->error(m_lastError);
            qCWarning(QT_BT_QNX) << Q_FUNC_INFO << "address not specified in service connect reply";
        }
    }
}
bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress& localAdapter)
{
    Q_UNUSED(localAdapter); //QNX always uses default local adapter
    if (protocolDescriptor(QBluetoothUuid::Rfcomm).isEmpty()) {
        qCWarning(QT_BT_QNX) << Q_FUNC_INFO << "Only SPP services can be registered on QNX";
        return false;
    }

    if (serverChannel() == -1)
        return false;

    if (__fakeServerPorts.key(serverChannel()) != 0) {
        if (!ppsSendControlMessage("register_server", 0x1101, attributes.value(QBluetoothServiceInfo::ServiceId).value<QBluetoothUuid>(), QString(),
                                   attributes.value(QBluetoothServiceInfo::ServiceName).toString(),
                              __fakeServerPorts.key(serverChannel()), BT_SPP_SERVER_SUBTYPE))
            return false;
        //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 {
        return false;
    }

    registered = true;
    return true;
}
bool QBluetoothServiceInfoPrivate::unregisterService()
{
    if (!registered)
        return false;
    if (serverChannel() == -1)
        return false;
    if ( __fakeServerPorts.key(serverChannel()) != 0) {
#ifdef QT_QNX_BT_BLUETOOTH
        QByteArray b_uuid = attributes.value(QBluetoothServiceInfo::ServiceId).
                value<QBluetoothUuid>().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<QBluetoothUuid>(), QString(),
                                   attributes.value(QBluetoothServiceInfo::ServiceName).toString(),
                                   __fakeServerPorts.key(serverChannel()), BT_SPP_SERVER_SUBTYPE)) {
            return false;
        }
#endif
        else {
            __fakeServerPorts.remove(__fakeServerPorts.key(serverChannel()));
            registered = false;
            return true;
        }
    }
    else {
        return false;
    }
}
void QBluetoothSocketPrivate::controlReply(ppsResult result)
{
#ifndef QT_QNX_BT_BLUETOOTH
    Q_Q(QBluetoothSocket);

    if (result.msg == QStringLiteral("connect_service")) {
        if (!result.errorMsg.isEmpty()) {
            qCWarning(QT_BT_QNX) << Q_FUNC_INFO << "Error connecting to service:" << result.errorMsg;
            errorString = result.errorMsg;
            q->setSocketError(QBluetoothSocket::UnknownSocketError);
            q->setSocketState(QBluetoothSocket::UnconnectedState);
            return;
        } else {
            qCDebug(QT_BT_QNX) << Q_FUNC_INFO << "Sending request for mount point";
            ppsSendControlMessage("get_mount_point_path", 0x1101, m_uuid, m_peerAddress.toString(), QString(), this, BT_SPP_CLIENT_SUBTYPE);
        }
    } else if (result.msg == QStringLiteral("get_mount_point_path")) {
        QString path;
        path = result.dat.first();
        qCDebug(QT_BT_QNX) << Q_FUNC_INFO << "PATH is" << path;

        if (!result.errorMsg.isEmpty()) {
            qCWarning(QT_BT_QNX) << Q_FUNC_INFO << result.errorMsg;
            errorString = result.errorMsg;
            q->setSocketError(QBluetoothSocket::UnknownSocketError);
            q->setSocketState(QBluetoothSocket::UnconnectedState);
            return;
        } else {
            qCDebug(QT_BT_QNX) << "Mount point path is:" << path;
            socket = ::open(path.toStdString().c_str(), O_RDWR);
            if (socket == -1) {
                errorString = qt_error_string(errno);
                q->setSocketError(QBluetoothSocket::UnknownSocketError);
                qCWarning(QT_BT_QNX) << Q_FUNC_INFO << socket << " error:" << errno << errorString; //TODO Try if this actually works

                q->disconnectFromService();
                q->setSocketState(QBluetoothSocket::UnconnectedState);
                return;
            }

            Q_Q(QBluetoothSocket);
            readNotifier = new QSocketNotifier(socket, QSocketNotifier::Read);
            QObject::connect(readNotifier, SIGNAL(activated(int)), this, SLOT(_q_readNotify()));
            connectWriteNotifier = new QSocketNotifier(socket, QSocketNotifier::Write, q);
            QObject::connect(connectWriteNotifier, SIGNAL(activated(int)), this, SLOT(_q_writeNotify()));

            connectWriteNotifier->setEnabled(true);
            readNotifier->setEnabled(true);
            q->setOpenMode(QIODevice::ReadWrite);
            state = QBluetoothSocket::ConnectedState;
            emit q->connected();
            ppsRegisterForEvent(QStringLiteral("service_disconnected"),this);
        }
    }
void QBluetoothServer::close()
{
    Q_D(QBluetoothServer);
    if (!d->socket) {
        d->m_lastError = UnknownError;
        emit error(d->m_lastError);
        return;
    }
    d->socket->close();
    delete d->socket;
    d->socket = 0;
    ppsSendControlMessage("deregister_server", 0x1101, d->m_uuid, QString(), QString(), 0);
    // force active object (socket) to run and shutdown socket.
    qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
}
void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address,
                                               const QBluetoothUuid &uuid,
                                               QIODevice::OpenMode openMode)
{
    Q_Q(QBluetoothSocket);
    Q_UNUSED(openMode);
    qCDebug(QT_BT_QNX) << "Connecting socket";

    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)), this, SLOT(_q_readNotify()));
    connectWriteNotifier = new QSocketNotifier(socket, QSocketNotifier::Write, q);
    QObject::connect(connectWriteNotifier, SIGNAL(activated(int)), this, 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;
    }

    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);
#endif
    q->setSocketState(QBluetoothSocket::ConnectingState);
}
void QBluetoothSocketPrivate::abort()
{
    Q_Q(QBluetoothSocket);
    qBBBluetoothDebug() << "Disconnecting service";
    if (q->state() != QBluetoothSocket::ClosingState)
        ppsSendControlMessage("disconnect_service", 0x1101, m_uuid, m_peerAddress.toString(), 0,
                          isServerSocket ? BT_SPP_SERVER_SUBTYPE : BT_SPP_CLIENT_SUBTYPE);
    delete readNotifier;
    readNotifier = 0;
    delete connectWriteNotifier;
    connectWriteNotifier = 0;

    ::close(socket);

    q->setSocketState(QBluetoothSocket::UnconnectedState);
    Q_EMIT q->disconnected();
    isServerSocket = false;
}
bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress& localAdapter)
{
    Q_UNUSED(localAdapter); //QNX always uses default local adapter
    if (protocolDescriptor(QBluetoothUuid::Rfcomm).isEmpty()) {
        qCWarning(QT_BT_QNX) << Q_FUNC_INFO << "Only SPP services can be registered on QNX";
        return false;
    }

    if (serverChannel() == -1)
        return false;

    if (__fakeServerPorts.key(serverChannel()) != 0) {
#ifdef QT_QNX_BT_BLUETOOTH
        QByteArray b_uuid = attributes.value(QBluetoothServiceInfo::ServiceId)
                .value<QBluetoothUuid>().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<long>(__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<QBluetoothUuid>(), 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 {
        return false;
    }

    registered = true;
    return true;
}
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;
    connectWriteNotifier = 0;

    ::close(socket);

    isServerSocket = false;
}
void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address, QBluetoothUuid uuid, QIODevice::OpenMode openMode)
{
    Q_UNUSED(openMode);
    qBBBluetoothDebug() << "Connecting socket";
    if (isServerSocket) {
        m_peerAddress = address;
        m_uuid = uuid;
        return;
    }

    if (state != QBluetoothSocket::UnconnectedState) {
        qBBBluetoothDebug() << "Socket already connected";
        return;
    }
    state = QBluetoothSocket::ConnectingState;

    m_uuid = uuid;
    m_peerAddress = address;

    ppsSendControlMessage("connect_service", 0x1101, uuid, address.toString(), this, BT_SPP_CLIENT_SUBTYPE);
    ppsRegisterForEvent(QStringLiteral("service_connected"),this);
    ppsRegisterForEvent(QStringLiteral("get_mount_point_path"),this);
    socketType = QBluetoothSocket::RfcommSocket;
}
void QBluetoothLocalDevicePrivate::setAccess(int access)
{
    ppsSendControlMessage("set_access", QStringLiteral("{\"access\":%1}").arg(access), this);
}
void QBluetoothLocalDevice::requestPairing(const QBluetoothAddress &address, Pairing pairing)
{
    Q_UNUSED(pairing);
    ppsSendControlMessage("initiate_pairing", QStringLiteral("{\"addr\":\"%1\"}").arg(address.toString()), this);
}
Example #16
0
void ppsDecodeControlResponse()
{
    ppsResult result;
    ResultType resType = UNKNOWN;

    if (ppsCtrlFD != -1) {
        char buf[ppsBufferSize];
        qt_safe_read(ppsCtrlFD, &buf, sizeof(buf) );
        if (buf[0] != '@')
            return;
        qCDebug(QT_BT_QNX) << "CTRL Response" << buf;

        pps_decoder_t ppsDecoder;
        pps_decoder_initialize(&ppsDecoder, 0);
        if (pps_decoder_parse_pps_str(&ppsDecoder, buf) == PPS_DECODER_OK) {
            pps_decoder_push(&ppsDecoder, 0);
            const char *buf;

            //The pps response can either be of type 'res', 'msg' or 'evt'
            if (pps_decoder_get_string(&ppsDecoder, "res", &buf) == PPS_DECODER_OK) {
                result.msg = QString::fromUtf8(buf);
                resType = RESPONSE;
            } else if (pps_decoder_get_string(&ppsDecoder, "msg", &buf) == PPS_DECODER_OK) {
                result.msg = QString::fromUtf8(buf);
                resType = MESSAGE;
            } else if (pps_decoder_get_string(&ppsDecoder, "evt", &buf) == PPS_DECODER_OK) {
                result.msg = QString::fromUtf8(buf);
                resType = EVENT;
            }

            if (pps_decoder_get_string(&ppsDecoder, "id",  &buf) == PPS_DECODER_OK)
                result.id = QString::fromUtf8(buf).toInt();

            //read out the error message if there is one
            if (pps_decoder_get_string(&ppsDecoder, "errstr", &buf) == PPS_DECODER_OK)
                result.errorMsg = QString::fromUtf8(buf);

            int dat;
            if (pps_decoder_get_int(&ppsDecoder, "err", &dat) == PPS_DECODER_OK) {
                result.error = dat;
            }

            //The dat object can be either a string or a array
            pps_node_type_t nodeType = pps_decoder_type(&ppsDecoder,"dat");
            if (nodeType == PPS_TYPE_STRING) {
                pps_decoder_get_string(&ppsDecoder,"dat",&buf);
                result.dat << QString::fromUtf8(buf);
            } else if (nodeType == PPS_TYPE_OBJECT || nodeType == PPS_TYPE_ARRAY) {
                pps_decoder_push(&ppsDecoder,"dat");
                pps_decoder_goto_index(&ppsDecoder, 0);
                int len = pps_decoder_length(&ppsDecoder);

                for (int i = 0; i < len; ++i) {
                    switch ( pps_decoder_type(&ppsDecoder, 0)) {
                    case PPS_TYPE_STRING:
                         result.dat << QString::fromUtf8(pps_decoder_name(&ppsDecoder));
                         pps_decoder_get_string(&ppsDecoder, 0, &buf);
                         result.dat << QString::fromUtf8(buf);
                         break;
                     case PPS_TYPE_NUMBER:
                         result.dat << QString::fromUtf8(pps_decoder_name(&ppsDecoder));
                         double dvalue;
                         pps_decoder_get_double(&ppsDecoder, 0, &dvalue);
                         result.dat << QString::number(dvalue);
                         break;
                     default:
                         pps_decoder_next(&ppsDecoder);
                     }
                 }
            } else {
                qCDebug(QT_BT_QNX) << "Control Response: No node type" << result.msg;
            }
        }
        pps_decoder_cleanup(&ppsDecoder);
    }

    if (result.msg == QStringLiteral("radio_init")) {
        qCDebug(QT_BT_QNX) << "Radio initialized";
    } else if (result.msg == QStringLiteral("access_changed") && __newHostMode != -1) {
        qCDebug(QT_BT_QNX) << "Access changed after radio init";
        ppsSendControlMessage("set_access", QStringLiteral("{\"access\":%1}").arg(__newHostMode), 0);
        __newHostMode = -1;
    }

    if (resType == RESPONSE) {
        QPair<int, QObject*> wMessage = takeObjectInWList(result.id);
        if (wMessage.second != 0)
            wMessage.second->metaObject()->invokeMethod(wMessage.second, "controlReply", Q_ARG(ppsResult, result));
    } else if (resType == EVENT) {
        //qCDebug(QT_BT_QNX) << "Distributing event" << result.msg;
        for (int i=0; i < evtRegistration.size(); i++) {
            if (result.msg == evtRegistration.at(i).first)
                evtRegistration.at(i).second->metaObject()->invokeMethod(evtRegistration.at(i).second, "controlEvent", Q_ARG(ppsResult, result));
        }
    }
}
void QBluetoothLocalDevicePrivate::powerOff()
{
    if (isValid())
        ppsSendControlMessage("radio_shutdown", this);
}
void QBluetoothLocalDevicePrivate::powerOn()
{
    if (isValid())
        ppsSendControlMessage("radio_init", this);
}