daniele86
daniele86

Reputation: 147

How to connect bluetooth headset with Qt libraries and manage input/output audio streams

I have a simple application which should be able to connect a bluetooth headset on my embedded device. I'm using qt libraries (QBluetooth) to connect bluetooth device. Headset has been correctly paired but I don't know how to manage audio once the socket is opened (in socketConnected() function). I don't know if it's the correct way to proceed. How can I send an audio file to bluetooth headset, manage volume or set input and output audio levels? Thanks in advice.

bluetoothMngmt.h

class BluetoothMgmt : public QObject { Q_OBJECT

public:
    BluetoothMgmt();
    ~BluetoothMgmt();    

private:
    //Classes
    QList<QBluetoothServiceInfo> *servicesInfo;

    //Variables/Objects
    QBluetoothLocalDevice *localDevice;
    QString localDeviceName;
    QBluetoothDeviceDiscoveryAgent *scanDevices;
    QBluetoothServiceDiscoveryAgent *scanServices;
    QBluetoothServer *rfcommServer;
    QBluetoothSocket *socket;

    //Functions

private slots:
    void startScan();
    void foundDevices(const QBluetoothDeviceInfo &device);
    void pairingDone(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing);
    void foundService(const QBluetoothServiceInfo &info);
    void socketConnected();
    void socketDisconnect();
    void readSocket();
    void socketError(QBluetoothSocket::SocketError error);
    void serviceDiscovered(const QBluetoothServiceInfo &service);
    void manageBtServices();

};

#endif // BLUETOOTHMGMT_H

bluetoothMngmt.cpp

//Constructor
BluetoothMgmt::BluetoothMgmt() {

    /* QT libraries */        
    /* Check if Bluetooth is available on this device */
    localDevice = new QBluetoothLocalDevice(this);
    scanDevices = new QBluetoothDeviceDiscoveryAgent(this);
    //scanDevices->setInquiryType(QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry);
    scanServices = new QBluetoothServiceDiscoveryAgent(this);
    servicesInfo = new QList<QBluetoothServiceInfo>;
    socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);

    /* Create a discovery agent and connect to its signals */
    connect(scanDevices, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),
            this, SLOT(foundDevices(QBluetoothDeviceInfo)));
    connect(localDevice, SIGNAL(pairingFinished(QBluetoothAddress, QBluetoothLocalDevice::Pairing)),
            this, SLOT(pairingDone(QBluetoothAddress, QBluetoothLocalDevice::Pairing)));
    connect(scanServices, SIGNAL(serviceDiscovered(QBluetoothServiceInfo)),
                this, SLOT(foundService(QBluetoothServiceInfo)) );
    connect(scanServices, SIGNAL(finished()),
            this, SLOT(manageBtServices()));
    connect(socket, SIGNAL(connected()),
            this, SLOT(socketConnected()) );
    connect(socket, SIGNAL(disconnected()),
            this, SLOT(socketDisconnect()) );
    connect(socket, SIGNAL(readyRead()),
            this, SLOT(readSocket()) );
    connect(socket, SIGNAL(error(QBluetoothSocket::SocketError)),
            this, SLOT(socketError(QBluetoothSocket::SocketError)) );


    if (localDevice->isValid()) {

        /* Turn Bluetooth on */
        localDevice->powerOn();

        /* Read local device name */
        localDeviceName = localDevice->name();
        qDebug() << "local device name:" << localDeviceName;

        /* Make it visible to others */
        localDevice->setHostMode(QBluetoothLocalDevice::HostDiscoverable);

        /* Get connected devices */
        QList<QBluetoothAddress> remotes;
        remotes = localDevice->connectedDevices();
        for(int i=0; i<remotes.size(); i++) {
            qDebug() << remotes.at(i).toString();
        }

    }

    // Start a discovery
    startScan();

}

//Destroyer
BluetoothMgmt::~BluetoothMgmt() {
    delete navisIntLogger;
    delete localDevice;
    delete scanDevices;
    delete scanServices;
    delete servicesInfo;
    delete socket;
}

void BluetoothMgmt::startScan()
{
    scanDevices->start();
    navisIntLogger->log(InternalLogger::LOG_INFO, "scan bluetooth devices started");
}

void BluetoothMgmt::foundDevices(const QBluetoothDeviceInfo &device) {


    qDebug() << "Found new device:" << device.name() << '(' << device.address().toString() << ')';


    if(QString::compare("WH-CH500", device.name(), Qt::CaseSensitive) == 0) {
        qDebug() << "WH-CH500 found with associated address:" << device.address().toString();
       //

        localDevice->requestPairing(device.address(), QBluetoothLocalDevice::Paired);

scanDevices->stop();


    }


    if(QString::compare(device.address().toString(), "D8:68:C3:5E:8A:48", Qt::CaseSensitive) == 0) {
        qDebug() << "CELLUILARE TROVATo";
        localDevice->requestPairing(device.address(), QBluetoothLocalDevice::Paired);
        scanDevices->stop();
    }

}

void BluetoothMgmt::pairingDone(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing) {
    if(pairing == QBluetoothLocalDevice::Paired || pairing == QBluetoothLocalDevice::AuthorizedPaired) {

        qDebug() << "PAIRING done";

        QBluetoothAddress address("00:18:09:8A:09:35"); //cuffia

        servicesInfo->clear();
        scanServices->setRemoteAddress(address);

        connect(scanServices, SIGNAL(serviceDiscovered(QBluetoothServiceInfo)),
                    this, SLOT(serviceDiscovered(QBluetoothServiceInfo)));
        scanServices->start();

    }
}

void BluetoothMgmt::foundService(const QBluetoothServiceInfo &info) {
    qDebug() << "TROVATO SERVIZIO E LO AGGIUNGO ALLA LISTA DI SERVICESINFO";
    QBluetoothServiceInfo infoCopy(info);
    //servicesInfo->append(infoCopy);
}

void BluetoothMgmt::socketConnected() {
    qDebug() << "Socket connected:" << socket->peerName();
}

void BluetoothMgmt::socketDisconnect() {
    qDebug() << "Socket disconnected";
}

void BluetoothMgmt::readSocket() {
    while (socket->canReadLine()) {
        qDebug()<<QString::fromLatin1(socket->readLine().toHex());
        qDebug()<<"hehehe";
    }
}

void BluetoothMgmt::socketError(QBluetoothSocket::SocketError error) {
    qDebug() << "Socket Error:" << socket->errorString();
}


// In your local slot, read information about the found devices
void BluetoothMgmt::serviceDiscovered(const QBluetoothServiceInfo &service)
{
    qDebug() << "Found new service:" << service.serviceName()
             << '(' << service.device().address().toString() << ')';
}

void BluetoothMgmt::manageBtServices() {
    QBluetoothAddress addressR("00:18:09:8A:09:35");
    quint16 port1 = 1; /* for headset and generic audio services */
    socket->connectToService(addressR, port1, QIODevice::ReadWrite);

}

Upvotes: 0

Views: 1364

Answers (1)

Manivannan Radhakannan
Manivannan Radhakannan

Reputation: 185

I believe there should be seperate class for Bluetooth Headset profile that you should use. The Classes shown in the question is about basic bluetooth operation. The Bluetooth Headset Profile may have the information on opening and closing SCO(for isochronous data) channel as well as sent AT+ commands to control volume over ACL channel

Upvotes: 1

Related Questions