code:
/*
 * QBtLocalDevice_win32.h
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "../QBtLocalDevice_win32.h"
#include <QBtAuxFunctions.h>

QBT_NAMESPACE_BEGIN

QBtAddress QBtLocalDevicePrivate::GetLocalDeviceAddress()
{
    BTINT32 result = BTSDK_FALSE;
    BTUINT8 devAddr[6] = {0};
    result = Btsdk_GetLocalDeviceAddress(devAddr);

    if(result == BTSDK_OK)
    {
        QByteArray btAddrr((char*)devAddr, 6);
        return QBtAddress::getAddressFromReversedArray(btAddrr);
    }
    return QBtAddress();
}

bool QBtLocalDevicePrivate::GetLimitedDiscoverableStatus()
{
    BTUINT16 pmode;
    BTINT32 retBool = BTSDK_FALSE;

    retBool = Btsdk_GetDiscoveryMode(&pmode);

    if((pmode & BTSDK_LIMITED_DISCOVERABLE) != 0)
        return true;

    return false;
}

void QBtLocalDevicePrivate::SetLimitedDiscoverableStatus(bool isDiscoverabilityLimited)
{
    BTUINT16 usMode = BTSDK_GENERAL_DISCOVERABLE * (!isDiscoverabilityLimited)
                        | BTSDK_LIMITED_DISCOVERABLE * isDiscoverabilityLimited
                        | BTSDK_CONNECTABLE
                        | BTSDK_PAIRABLE;

    Btsdk_SetDiscoveryMode(usMode);

    return;
}

QBtDevice::DeviceMajor QBtLocalDevicePrivate::GetDeviceClass()
{
    BTUINT32 devClass;
    BTINT32 result = BTSDK_FALSE;
    result = Btsdk_GetLocalDeviceClass(&devClass);

    if(result != BTSDK_OK)
        return QBtDevice::Uncategorized;

    if(devClass & BTSDK_DEVCLS_COMPUTER)
        return QBtDevice::Computer;
    else if(devClass & BTSDK_DEVCLS_PHONE)
        return QBtDevice::Phone;
    else if(devClass & BTSDK_DEVCLS_LAP)
        return QBtDevice::LANAccess;
    else if(devClass & BTSDK_DEVCLS_AUDIO)
        return QBtDevice::AudioVideo;
    else if(devClass & BTSDK_DEVCLS_PERIPHERAL)
        return QBtDevice::Peripheral;
    else if(devClass & BTSDK_DEVCLS_IMAGE)
        return QBtDevice::Imaging;
    else if(devClass & BTSDK_DEVCLS_IMAGE)
        return QBtDevice::Imaging;
    else if(devClass & BTSDK_DEVCLS_WEARABLE)
        return QBtDevice::Wearable;
    else
        return QBtDevice::Uncategorized;
}

void QBtLocalDevicePrivate::SetDeviceClass(QBtDevice::DeviceMajor classId)
{
    BTUINT32 devClass;
    BTINT32 result = BTSDK_FALSE;
    result = Btsdk_GetLocalDeviceClass(&devClass);

    if(result != BTSDK_OK)
        return;

    QBtDevice::DeviceMajor currentDeviceClass = GetDeviceClass();

    BTUINT32 newDevClass = (devClass ^ (currentDeviceClass * 0x100)) | (classId * 0x100);

    Btsdk_SetLocalDeviceClass(newDevClass);
}

void QBtLocalDevicePrivate::SetLocalDeviceName(const QString & devName)
{
    Btsdk_SetLocalName((BTUINT8*)devName.toUtf8().constData(), devName.size());
}

QString QBtLocalDevicePrivate::GetLocalDeviceName()
{
    BTINT32 result = BTSDK_FALSE;
    BTUINT8 devName[BTSDK_DEVNAME_LEN] = {0};
    BTUINT16 nameSize = BTSDK_DEVNAME_LEN;

    result = Btsdk_GetLocalName(devName, &nameSize);

    if(result == BTSDK_OK)
        return QString::fromUtf8((char*)devName);
    else
        return "Unknown";
}

////////////////////////////////

bool QBtLocalDevicePrivate::IsBluetoothSupported()
{
    return Btsdk_IsServerConnected();
}

void QBtLocalDevicePrivate::AskUserTurnOnBtPower()
{
    Btsdk_StartBluetooth();
}

bool QBtLocalDevicePrivate::GetBluetoothPowerState()
{
    return Btsdk_IsBluetoothReady();
}

bool QBtLocalDevicePrivate::SetBluetoothPowerState (bool /*value*/)
{
	return false;
}

/////////////////////////////////

bool QBtLocalDevicePrivate::AddNewDevice(const QBtDevice& device)
{
    BTUINT8 devAddr[6] = {0};
    BTDEVHDL devHandle = BTSDK_INVALID_HANDLE;
    QByteArray addrArray = device.getAddress().toReversedByteArray();
    memcpy(devAddr, addrArray.constData(), addrArray.size());
    devHandle = Btsdk_AddRemoteDevice(devAddr);

    return (devHandle != BTSDK_INVALID_HANDLE);
}

bool QBtLocalDevicePrivate::DeleteDevice(const QBtDevice& device)
{
    return QBtLocalDevicePrivate::DeleteDevice(device.getAddress());
}

bool QBtLocalDevicePrivate::DeleteDevice(const QBtAddress& address)
{
    BTINT32 result = BTSDK_FALSE;
    //get device handle
    BTDEVHDL devHandle = BTSDK_INVALID_HANDLE;
    BTUINT8 btAddr [6]= {0};
    QByteArray btAddrQt = address.toReversedByteArray();
    memcpy(btAddr, btAddrQt.constData(), btAddrQt.size());
    devHandle = Btsdk_GetRemoteDeviceHandle(btAddr);

    if(devHandle == BTSDK_INVALID_HANDLE)
        return false;

    result = Btsdk_DeleteRemoteDeviceByHandle (devHandle);

    return (result == BTSDK_OK);
}

bool QBtLocalDevicePrivate::UnpairDevice(const QBtDevice& device)
{
    return QBtLocalDevicePrivate::UnpairDevice(device.getAddress());
}

bool QBtLocalDevicePrivate::UnpairDevice(const QBtAddress& address)
{
    BTINT32 result = BTSDK_FALSE;
    //get device handle
    BTDEVHDL devHandle = BTSDK_INVALID_HANDLE;
    BTUINT8 btAddr [6]= {0};
    QByteArray btAddrQt = address.toReversedByteArray();
    memcpy(btAddr, btAddrQt.constData(), btAddrQt.size());
    devHandle = Btsdk_GetRemoteDeviceHandle(btAddr);

    if(devHandle == BTSDK_INVALID_HANDLE)
        return false;

    result = Btsdk_UnPairDevice (devHandle);

    return (result == BTSDK_OK);
}

//////////////////////////////////////////////////////////////////////////
bool QBtLocalDevicePrivate::IsVisible()
{
	BTUINT16 pmode;
	BTINT32 retBool = BTSDK_FALSE;

	retBool = Btsdk_GetDiscoveryMode(&pmode);

	if((pmode & BTSDK_LIMITED_DISCOVERABLE || pmode & BTSDK_DISCOVERABLE) != 0)
		return true;

	return false;
}

void QBtLocalDevicePrivate::SetVisible (bool value)
{
	BTUINT16 usMode =  BTSDK_CONNECTABLE
						| BTSDK_PAIRABLE | BTSDK_DISCOVERABLE*((int)value);

	Btsdk_SetDiscoveryMode(usMode);

	return;
}

QBT_NAMESPACE_END


code:
/*
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef QBTLOCALDEVICE_H
#define QBTLOCALDEVICE_H

#include <QBtGlobal.h>
#include <QBtTypes.h>
#include <QtCore/QObject>

QBT_NAMESPACE_BEGIN

//This class contains only static functions. How can it be used through QML
// TYPE == Q_STATIC

class DLL_EXPORT QBtLocalDevice //: public QObject
{
    //Q_OBJECT
public:

    ///////////////////////////////////////
    ///	 Bluetooth local properties		///
    ///////////////////////////////////////
    /**
     * Returns if possible the local device address
     */
    static QBtAddress getLocalDeviceAddress();

    /**
     * Returns true if local device is visible to other devices.
     */
    static bool isVisible ();

    /**
     * Sets the device visibility to other devices.
     * @param value true -> visible, false -> invisible
     */
    static void setVisible (bool value);

    static QBtDevice::DeviceMajor getDeviceClass();

    /**
     * Sets the UUID of the device that characterizes the device's type.
     * The possible enumeration values passed as argument are defined in
     * QBtDevice::DeviceMajor.
     */
    static void setDeviceClass(QBtDevice::DeviceMajor classId);

    /**
     * Sets the name of the device throught which it will be identified by other
     * devices during SDP discovery.
     */
    static void setLocalDeviceName (const QString & deviceName);

    /**
     * Get local device name.
     * @return device name
     */
    static QString getLocalDeviceName();

    /**
     * Returns true if bluetooth hardware exists and is plugged in.
     */
    static bool isBluetoothSupported();

    /**
     * Symbian specific function.
     * Used if bluetooth is powered off, showing a dialog that asks permission
     * from the user to power on bluetooth.
     */
    static void askUserTurnOnBtPower();

    /**
     * Symbian specific function.
     * Turns on/off bluetooth. Returns true is operation was sucessful.
     */
    static bool setBluetoothPowerState (bool value);

    /**
     * Returns true/false if bluetooth hardware is powered on/off respectively.
     */
    static bool getBluetoothPowerState();

    /**
     * Add a new device in the bluetooth registry.
     * @param device the device to be added
     * @return true upon success, else false
     */
    static bool addNewDevice(const QBtDevice& device);

    /**
     * Delete a device from the bluetooth registry.
     * @param device the device to be deleted
     * @return true upon success, else false. If device doesn't exists in the registry the also false
     */
    static bool deleteDevice(const QBtDevice& device);

    /**
     * Delete a device from the bluetooth registry using the bluetooth address.
     * @param address the device address of the device to be delete
     * @return true upon success, else false. If device doesn't exists in the registry the also false
     */
    static bool deleteDevice(const QBtAddress& address);

    /**
     * Breaks the pairing between the local device and the device passed as argument.
     *
     * @param device the device class containing the information of the device to be unpaired.
     */
    static bool unpairDevice(const QBtDevice& device);

    /**
     * Breaks the pairing between the local device and the remote device identified by
     * the bluetooth address passed as argument.
     *
     * @param address the bluetooth address of the remote device.
     */
    static bool unpairDevice(const QBtAddress& address);
};

QBT_NAMESPACE_END

Q_DECLARE_METATYPE(QBT_PREPEND_NAMESPACE(QBtLocalDevice))

#if QT_VERSION >= 0x040700
//QML_DECLARE_TYPEINFO(QBT_PREPEND_NAMESPACE(QBtLocalDevice))
#endif

#endif // QBTLOCALDEVICE_H

repo_name: snapshot/qbluetooth

license: unknown


code:
/*
 * QBtLocalDevice_stub.h
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef QBTLOCALDEVICE_STUB_H_
#define QBTLOCALDEVICE_STUB_H_

class QBtLocalDevicePrivate
{
public:

	///////////////////////////////////////
	///	 Bluetooth local properties		///
	///////////////////////////////////////
	static QBtAddress GetLocalDeviceAddress();
	static bool GetLimitedDiscoverableStatus();
	static void SetLimitedDiscoverableStatus(bool isDiscoverabilityLimited);
	static QBtDevice::DeviceMajor GetDeviceClass();
	static void SetDeviceClass(QBtDevice::DeviceMajor classId);
	static void SetLocalDeviceName(const QString & deviceName);
	static QString GetLocalDeviceName();

	///////////////////////////////
	///	 Bluetooth Hardware		///
	///////////////////////////////
	static bool IsBluetoothSupported();
	static void AskUserTurnOnBtPower();
	static bool GetBluetoothPowerState();
	static bool SetBluetoothPowerState (bool value);

	///////////////////////////////
	///	 Bluetooth Registry		///
	///////////////////////////////
	static bool AddNewDevice(const QBtDevice& device);
	static bool DeleteDevice(const QBtDevice& device);
	static bool DeleteDevice(const QBtAddress& address);
	static bool UnpairDevice(const QBtDevice& device);
	static bool UnpairDevice(const QBtAddress& address);

};

#endif /* QBTLOCALDEVICE_STUB_H_ */


code:
/*
 * QBtLocalDevice_symbian.h
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef QBTLOCALDEVICE_SYMBIAN_H_
#define QBTLOCALDEVICE_SYMBIAN_H_

#include <e32base.h>
#include <e32std.h>
#include <featureinfo.h>
#include <featdiscovery.h>
#include <btnotifierapi.h>
#include <centralrepository.h>
#include <BTServerSDKCRKeys.h>
#include <btdevice.h>
#include <btmanclient.h>
#include <e32property.h>
#include <bt_subscribe.h>

#include <QBtLocalDevice.h>

class QBtLocalDevicePrivate
{
public:

    ///////////////////////////////////////
    ///	 Bluetooth local properties		///
    ///////////////////////////////////////
    static QBtAddress GetLocalDeviceAddress();
    static TBool IsVisible();
    static void SetVisible (TBool value);
    static QBtDevice::DeviceMajor GetDeviceClass();
    static void SetDeviceClass(QBtDevice::DeviceMajor classId);
    static void SetLocalDeviceName (const QString & deviceName);
    static QString GetLocalDeviceName();

    ///////////////////////////////
    ///	 Bluetooth Hardware		///
    ///////////////////////////////
    static TBool IsBluetoothSupported();
    static void AskUserTurnOnBtPower();
    static TBool GetBluetoothPowerState();
    static TBool SetBluetoothPowerState (TBool value);

    ///////////////////////////////
    ///	 Bluetooth Registry		///
    ///////////////////////////////
    static TBool AddNewDevice(const QBtDevice& device);
    static TBool DeleteDevice(const QBtAddress& address);
    static TBool UnpairDevice(const QBtAddress& address);

private:
    static TBool DefineProperty(TUint propertyId, RProperty::TType typeEnum);
    static TBool DeleteOrUnpairDevice(const QBtAddress& address, TBool unpair);

private:
    QBtLocalDevice* p_ptr;
};

#endif /* QBTLOCALDEVICE_SYMBIAN_H_ */


code:
/*
 * QBtLocalDevice_win32.h
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef QBTLOCALDEVICE_WIN32_H_
#define QBTLOCALDEVICE_WIN32_H_

#include <QBtTypes.h>
#include <QBtAuxFunctions.h>

QBT_NAMESPACE_BEGIN

class QBtLocalDevicePrivate
{
public:

    ///////////////////////////////////////
    ///	 Bluetooth local properties		///
    ///////////////////////////////////////
    static QBtAddress GetLocalDeviceAddress();
    static bool GetLimitedDiscoverableStatus();
    static void SetLimitedDiscoverableStatus(bool isDiscoverabilityLimited);
    static QBtDevice::DeviceMajor GetDeviceClass();
    static void SetDeviceClass(QBtDevice::DeviceMajor classId);
    static void SetLocalDeviceName(const QString & devName);
    static QString GetLocalDeviceName();

	static bool IsVisible();
	static void SetVisible (bool value);

    ///////////////////////////////
    ///	 Bluetooth Hardware		///
    ///////////////////////////////
    static bool IsBluetoothSupported();
    static void AskUserTurnOnBtPower();
    static bool GetBluetoothPowerState();
    static bool SetBluetoothPowerState (bool value);

    ///////////////////////////////
    ///	 Bluetooth Registry		///
    ///////////////////////////////
    static bool AddNewDevice(const QBtDevice& device);
    static bool DeleteDevice(const QBtDevice& device);
    static bool DeleteDevice(const QBtAddress& address);
    static bool UnpairDevice(const QBtDevice& device);
    static bool UnpairDevice(const QBtAddress& address);
};

QBT_NAMESPACE_END

#endif /* QBTLOCALDEVICE_WIN32_H_ */


code:
/*
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef QBLUETOOTH_H
#define QBLUETOOTH_H

#include <QBtAuxFunctions.h>
#include <QBtGlobal.h>

#include <QBtTypes.h>
#include <QBtDeviceDiscoverer.h>
#include <QBtSingleDeviceSelectorUI.h>
#include <QBtServiceDiscoverer.h>
#include <QBtServiceDiscovererForAll.h>
#include <QBtServiceAdvertiser.h>
#include <QBtSerialPortServer.h>
#include <QBtSerialPortClient.h>
#include <QBtObjectExchangeClient.h>
#include <QBtObjectExchangeServer.h>
#include <QBtLocalDevice.h>

//using namespace QBluetooth;

namespace QBluetooth
{
    static void registerTypes()
    {
        qRegisterMetaType<QBT_PREPEND_NAMESPACE(QBtDevice)>("QBtDevice");
        qRegisterMetaType<QBT_PREPEND_NAMESPACE(QBtService)>("QBtService");
        qRegisterMetaType<QBT_PREPEND_NAMESPACE(QBtAddress)>("QBtAddress");
        qRegisterMetaType<QBT_PREPEND_NAMESPACE(QBtUuid)>("QBtUuid");
        qRegisterMetaType<QBT_PREPEND_NAMESPACE(QBtRemoteFileInfo)>("QBtRemoteFileInfo");
    }

    static void registerQMLTypes()
    {
       /* #if QT_VERSION > 0x040700
        qmlRegisterType<QBT_PREPEND_NAMESPACE(QBtConstants)>(QML_LIBRARY_NAME, 1, 0, "QBtConstants");
        qmlRegisterType<QBT_PREPEND_NAMESPACE(QBtUuid)>(QML_LIBRARY_NAME, 1, 0, "QBtUuid");
        qmlRegisterType<QBT_PREPEND_NAMESPACE(QBtAddress)>(QML_LIBRARY_NAME, 1, 0, "QBtAddress");
        qmlRegisterType<QBT_PREPEND_NAMESPACE(QBtDevice)>(QML_LIBRARY_NAME, 1, 0, "QBtDevice");
        qmlRegisterType<QBT_PREPEND_NAMESPACE(QBtService)>(QML_LIBRARY_NAME, 1, 0, "QBtService");
        qmlRegisterType<QBT_PREPEND_NAMESPACE(QBtDeviceDiscoverer)>(QML_LIBRARY_NAME, 1, 0, "QBtDeviceDiscoverer");
        qmlRegisterType<QBT_PREPEND_NAMESPACE(QBtRemoteFileInfo)>(QML_LIBRARY_NAME, 1, 0, "QBtRemoteFileInfo");
        //qmlRegisterType<QBtServiceDiscoverer>("QBtServiceDiscoverer", 1, 0, "QBtServiceDiscoverer");
        //qmlRegisterType<QBtServiceAdvertiser>("QBtServiceAdvertiser", 1, 0, "QBtServiceAdvertiser");
        //qmlRegisterType<QBtLocalDevice>("QBtLocalDevice", 1, 0, "QBtLocalDevice");
        //qmlRegisterType<QBtSingleDeviceSelectorUI>("QBtSingleDeviceSelectorUI", 1, 0, "QBtSingleDeviceSelectorUI");
        //qmlRegisterType<QBtSerialPortServer>("QBtSerialPortServer", 1, 0, "QBtSerialPortServer");
        //qmlRegisterType<QBtSerialPortClient>("QBtSerialPortClient", 1, 0, "QBtSerialPortClient");
        //qmlRegisterType<QBtObjectExchangeServer>("QBtObjectExchangeServer", 1, 0, "QBtObjectExchangeServer");
        //qmlRegisterType<QBtObjectExchangeClient>("QBtObjectExchangeClient", 1, 0, "QBtObjectExchangeClient");
        #endif*/
    }

}

#endif // QBLUETOOTH_H


code:
uid3 = 0xA003328D

QT += core

VERSION = 2.0.1

#lessThan(QT_VERSION, 4.7):
#else:QT += declarative

TEMPLATE = lib
TARGET   = QBluetoothZero
DEFINES  += BLUETOOTH_LIB

PUBLIC_HEADERS += QBtGlobal.h \
    QBtAuxFunctions.h \
	DeviceDiscoverer/QBtDeviceDiscoverer.h \
    BTTypes/QBtAddress.h \
    BTTypes/QBtDevice.h \
    BTTypes/QBtService.h \
    BTTypes/QBtConstants.h \
    BTTypes/QBtTypes.h \
    BTTypes/QBtUuid.h \
	BTTypes/QBtRemoteFileInfo.h \
    DeviceDiscoverer/QBtSingleDeviceSelectorUI.h \
    ServiceDiscoverer/QBtServiceDiscoverer.h \
    ServiceDiscoverer/QBtServiceDiscovererForAll.h \
    ServiceAdvertiser/QBtServiceAdvertiser.h \
    Connection/SerialPort/Server/QBtSerialPortServer.h \
    Connection/SerialPort/Client/QBtSerialPortClient.h \
    Connection/ObjectExchange/Client/QBtObjectExchangeClient.h \
    LocalDevice/QBtLocalDevice.h \
    Connection/ObjectExchange/Server/QBtObjectExchangeServer.h \
    QBluetoothZero.h

HEADERS += $$PUBLIC_HEADERS

SOURCES += Connection/ObjectExchange/Server/Impl/QBtObjectExchangeServer.cpp \
    LocalDevice/Impl/QBtLocalDevice.cpp \
    Connection/ObjectExchange/Client/Impl/QBtObjectExchangeClient.cpp \
    Connection/SerialPort/Client/Impl/QBtSerialPortClient.cpp \
    Connection/SerialPort/Server/Impl/QBtSerialPortServer.cpp \
    ServiceAdvertiser/Impl/QBtServiceAdvertiser.cpp \
    BTTypes/Impl/QBtService.cpp \
	BTTypes/Impl/QBtRemoteFileInfo.cpp \
    ServiceDiscoverer/Impl/QBtServiceDiscoverer.cpp \
    ServiceDiscoverer/Impl/QBtServiceDiscovererForAll.cpp \
    DeviceDiscoverer/Impl/QBtSingleDeviceSelectorUI.cpp \
    DeviceDiscoverer/Impl/QBtDeviceDiscoverer.cpp \
    BTTypes/Impl/QBtAddress.cpp \
    BTTypes/Impl/QBtDevice.cpp \
    BTTypes/Impl/QBtUuid.cpp \
    QBtAuxFunctions.cpp

symbian {
	# fix for Qt Creator to find the symbian headers
	INCLUDEPATH += $$EPOCROOT/epoc32/include

    deploy.path = $$EPOCROOT
    exportheaders.sources = $$PUBLIC_HEADERS
    exportheaders.path = epoc32/include

    INCLUDEPATH += $$deploy.path$$exportheaders.path/QBluetoothZero/

    INCLUDEPATH += $$deploy.path$$exportheaders.path

    TARGET.UID3 = 0xA003328D

    TARGET.EPOCALLOWDLLDATA = 1

    HEADERS += Connection/ObjectExchange/Server/QBtObjectExchangeServer_symbian.h \
        LocalDevice/QBtLocalDevice_symbian.h \
        Connection/ObjectExchange/Client/QBtObjectExchangeClient_symbian.h \
        Connection/SerialPort/Client/QBtSerialPortClient_symbian.h \
        Connection/SerialPort/Server/QBtSerialPortServer_symbian.h \
        ServiceAdvertiser/QBtServiceAdvertiser_symbian.h \
        ServiceDiscoverer/QBtServiceDiscoverer_symbian.h \
        DeviceDiscoverer/QBtDeviceDiscoverer_symbian.h \
        DeviceDiscoverer/QBtSingleDeviceSelectorUI_symbian.h \
        DeviceDiscoverer/BtDeviceFinderDlg_symbian.h

    SOURCES += Connection/ObjectExchange/Server/Impl/QBtObjectExchangeServer_symbian.cpp \
        LocalDevice/Impl/QBtLocalDevice_symbian.cpp \
        Connection/ObjectExchange/Client/Impl/QBtObjectExchangeClient_symbian.cpp \
        Connection/SerialPort/Client/Impl/QBtSerialPortClient_symbian.cpp \
        Connection/SerialPort/Server/Impl/QBtSerialPortServer_symbian.cpp \
        ServiceAdvertiser/Impl/QBtServiceAdvertiser_symbian.cpp \
        ServiceDiscoverer/Impl/QBtServiceDiscoverer_symbian.cpp \
        DeviceDiscoverer/Impl/QBtDeviceDiscoverer_symbian.cpp \
        DeviceDiscoverer/Impl/QBtSingleDeviceSelectorUI_symbian.cpp \
        DeviceDiscoverer/Impl/BtDeviceFinderDlg_symbian.cpp

    # more libs based on s60 version
    contains (S60_VERSION, 3.1):BT_PLUGIN_LIB = -lbteng
    else:BT_PLUGIN_LIB = -lbtengsettings

    #
    LIBS += -lbluetooth \
        -lbtextnotifiers \
        -lsdpdatabase \
        -lsdpagent \
        -lirobex \
        -lefsrv \
        -lfeatdiscovery \
        -lcentralrepository \
        -lbafl \
        -leikcore \
        -lcone \
        -lbtdevice \
        -lbtmanclient \
        -lesock \

    LIBS += $$BT_PLUGIN_LIB

#    TARGET.CAPABILITY = All -TCB -AllFiles -DRM
    TARGET.CAPABILITY += LocalServices \
        NetworkServices \
        ReadUserData \
        UserEnvironment \
        WriteUserData \
         Location

    for(header, exportheaders.sources):BLD_INF_RULES.prj_exports += "$$header $$deploy.path$$exportheaders.path/QBluetoothZero/$$basename(header)"

	# add this for Qt Creator to generate a pkg file, it seems to be a bug in the current version (2.0.0)
        addFiles.sources = QBluetoothZero.dll
	addFiles.path = /sys/bin
	DEPLOYMENT += addFiles
}

else {
    win32 {
        LIBS += -lBlueSoleil_SDK_2.0.5/Bin/BsSDK

        INCLUDEPATH = . \
            BTTypes	\
            BlueSoleil_SDK_2.0.5/SDKheaders/include \
            Connection/ObjectExchange/Server \
            LocalDevice \
            Connection/ObjectExchange/Client \
            Connection/SerialPort/Client \
            Connection/SerialPort/Server \
            ServiceAdvertiser \
            ServiceDiscoverer \
            DeviceDiscoverer \
            WinSerialPort
        DESTDIR += $$(QTDIR)/QBluetoothZero/bin
        HEADERS += Connection/ObjectExchange/Server/QBtObjectExchangeServer_win32.h \
            LocalDevice/QBtLocalDevice_win32.h \
            Connection/ObjectExchange/Client/QBtObjectExchangeClient_win32.h \
            Connection/SerialPort/Client/QBtSerialPortClient_win32.h \
            Connection/SerialPort/Server/QBtSerialPortServer_win32.h \
            ServiceAdvertiser/QBtServiceAdvertiser_win32.h \
            ServiceDiscoverer/QBtServiceDiscoverer_win32.h \
            DeviceDiscoverer/QBtDeviceDiscoverer_win32.h \
			DeviceDiscoverer/QBtSingleDeviceSelectorUI_stub.h \
            WinSerialPort/Tserial_event.h
        SOURCES += Connection/ObjectExchange/Server/Impl/QBtObjectExchangeServer_win32.cpp \
            LocalDevice/Impl/QBtLocalDevice_win32.cpp \
            Connection/ObjectExchange/Client/Impl/QBtObjectExchangeClient_win32.cpp \
            Connection/SerialPort/Client/Impl/QBtSerialPortClient_win32.cpp \
            Connection/SerialPort/Server/Impl/QBtSerialPortServer_win32.cpp \
            ServiceAdvertiser/Impl/QBtServiceAdvertiser_win32.cpp \
            ServiceDiscoverer/Impl/QBtServiceDiscoverer_win32.cpp \
            DeviceDiscoverer/Impl/QBtSingleDeviceSelectorUI_stub.cpp \
            DeviceDiscoverer/Impl/QBtDeviceDiscoverer_win32.cpp \
            WinSerialPort/Tserial_event.cpp

		exportheaders.sources = $$PUBLIC_HEADERS

		for(header, exportheaders.sources){
                        DESTDIR += "$$header $$DESTDIR/include/$$basename(header)"
		}
    }
    else {
        HEADERS += Connection/ObjectExchange/Server/QBtObjectExchangeServer_stub.h \
            LocalDevice/QBtLocalDevice_stub.h \
            Connection/ObjectExchange/Client/QBtObjectExchangeClient_stub.h \
            Connection/SerialPort/Client/QBtSerialPortClient_stub.h \
            Connection/SerialPort/Server/QBtSerialPortServer_stub.h \
            ServiceAdvertiser/QBtServiceAdvertiser_stub.h \
            ServiceDiscoverer/QBtServiceDiscoverer_stub.h \
            DeviceDiscoverer/QBtDeviceDiscoverer_stub.h
        SOURCES += Connection/ObjectExchange/Server/Impl/QBtObjectExchangeServer_stub.cpp \
            LocalDevice/Impl/QBtLocalDevice_stub.cpp \
            Connection/ObjectExchange/Client/Impl/QBtObjectExchangeClient_stub.cpp \
            Connection/SerialPort/Client/Impl/QBtSerialPortClient_stub.cpp \
            Connection/SerialPort/Server/Impl/QBtSerialPortServer_stub.cpp \
            ServiceAdvertiser/Impl/QBtServiceAdvertiser_stub.cpp \
            ServiceDiscoverer/Impl/QBtServiceDiscoverer_stub.cpp \
            DeviceDiscoverer/Impl/QBtDeviceDiscoverer_stub.cpp
    }
}


code:
#include "QBtAuxFunctions.h"

#ifdef Q_OS_WIN32
bool QBtAuxFunctions::InitBthSdk()
{
    if ( sdkInitializationCounter == 0) /* not connected with BlueSoleil */
    {
        if (Btsdk_Init() != BTSDK_OK)
            return false;

        if (Btsdk_IsBluetoothReady() == BTSDK_FALSE)
            Btsdk_StartBluetooth();

        BTUINT16 discoveryFlags = BTSDK_CONNECTABLE | BTSDK_PAIRABLE | BTSDK_GENERAL_DISCOVERABLE;
        Btsdk_SetDiscoveryMode(discoveryFlags);
        Btsdk_SetLocalDeviceClass(BTSDK_COMPCLS_DESKTOP);
    }
    sdkInitializationCounter++;

    return true;
}

void QBtAuxFunctions::DeinitBthSdk()
{
    if(Btsdk_IsSDKInitialized() && sdkInitializationCounter > 0)
    {
        sdkInitializationCounter--;
        if(sdkInitializationCounter == 0)
            Btsdk_Done();
    }
}

BTDEVHDL QBtAuxFunctions::GetDeviceHandle(const QBtAddress& address)
{
    //get device handle
    BTDEVHDL devHandle = BTSDK_INVALID_HANDLE;
    BTUINT8 btAddr [6]= {0};
    QByteArray btAddrQt = address.toReversedByteArray();
    memcpy(btAddr, btAddrQt.constData(), btAddrQt.size());
    devHandle = Btsdk_GetRemoteDeviceHandle(btAddr);
    return devHandle;
}

#endif //WIN32


code:
/*
 * auxFunctions_symbian.h
 *
 *      Author: Ftylitakis Nikolaos, Luis Valente
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef AUXFUNCTIONS_SYMBIAN_H_
#define AUXFUNCTIONS_SYMBIAN_H_

#include <QBtGlobal.h>

QBT_NAMESPACE_BEGIN

template <class T> inline void SafeDelete(T* &ptr)
{
	if(ptr)
	{
		delete ptr;
		ptr = 0;
	}
}

//#ifdef Q_OS_SYMBIAN
#include <QtCore/QString>
#include <QtGui/QMessageBox>
#include <QtCore/QDir>
#include <QtCore/QDebug.h>

inline void _Debug_Msg (const QString & m, const QString & file, int line)
{
    qDebug() << "file: " << file << " line: " << line << " " << m;
}

inline void _Assert_Msg (const QString msg, const QString & file, int line)
{
    // strip directory info
    int index = file.lastIndexOf("/");
    QString f = file.mid (index+1);
    QString m = QString ("file: %1 line: %2\n%3").arg (f).arg(line).arg(msg);

    //
    _Debug_Msg (m, file, line);

    //
    QMessageBox::information(0, "assert failed", m);
    Q_ASSERT (false);
}

inline void _Assert_Msg2 (const QString & msg1, const QString & msg2, const QString & file, int line)
{
   _Assert_Msg (QString("%1 : %2").arg(msg1).arg(msg2), file, line);
}

inline void _Break_Here (const QString & file, int line)
{
    // strip directory info
    int index = file.lastIndexOf("/");
    QString f = file.mid (index+1);
    QString m = QString ("file: %1 line: %2").arg (f).arg (line);

    //
    _Debug_Msg (m, file, line);

    //
    QMessageBox::information(0, "code break", m);
    Q_ASSERT (false);
}

inline void _Break_Here (const QString & file, const QString & line)
{
	// strip directory info
	int index = file.lastIndexOf("/");
	QString f = file.mid (index+1);
	QString m = QString ("file: %1 line: %2").arg (f, line);

	QMessageBox::information(0, "code break", m);
	Q_ASSERT (false);
}

#ifdef QT_DEBUG
    #define BT_DEBUG_MSG(msg) (_Debug_Msg((msg),__FILE__,__LINE__) )
    #define BT_BREAK_HERE() (_Break_Here(__FILE__, QString::number(__LINE__)) )
    #define BT_ASSERT_MSG(test, msg) ((!(test)) ? _Assert_Msg((msg), __FILE__, __LINE__) : qt_noop() )
    #define BT_ASSERT_MSG2(test, msg1, msg2) ((!(test)) ? _Assert_Msg2((msg1), (msg2), __FILE__, __LINE__) : qt_noop() )

#else

    #define BT_DEBUG_MSG(msg) {}
    #define BT_ASSERT_MSG_X(test, where, msg) {}
    #define BT_ASSERT_MSG(test, msg) {}
    #define BT_ASSERT_MSG2(test, msg1, msg2) {}
    #define BT_BREAK_HERE() {}

//#endif

#endif

#ifdef Q_OS_WIN32

#include <windows.h>
#include <conio.h>
#include <QBtAddress.h>

using namespace std;

// used to have the number of the classes that use the Bluesoleil SDK.
// if the number reaches zero the sdk is deinitialized.
static size_t sdkInitializationCounter = 0;

//forward declaration

#ifdef BLUETOOTH_LIB
extern "C"{
#include "./BlueSoleil_SDK_2.0.5/include/Btsdk_ui.h"
}
#else
class BTDEVHDL;
#endif

class DLL_EXPORT QBtAuxFunctions
{
public:
    static bool InitBthSdk();
    static void DeinitBthSdk();
    static BTDEVHDL GetDeviceHandle(const QBtAddress& address);
};

#endif // Q_OS_WIN32

QBT_NAMESPACE_END
#endif /* AUXFUNCTIONS_SYMBIAN_H_ */


code:
/*
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef QBTGLOBAL_H
#define QBTGLOBAL_H

#include <QtCore/qglobal.h>
#include <QtCore/QMetaType>

#ifdef BLUETOOTH_LIB
#define DLL_EXPORT Q_DECL_EXPORT
#else
#define DLL_EXPORT Q_DECL_IMPORT
#endif

#if QT_VERSION >= 0x040700
//#include <QtDeclarative>
#endif
/*
#define ENABLE_QBLUETOOTH_NAMESPACE
*/
#define QML_LIBRARY_NAME "QBluetooth"

#ifdef ENABLE_QBLUETOOTH_NAMESPACE
#define QBT_PREPEND_NAMESPACE(name)	::QBluetooth::name
#define QBT_NAMESPACE_NAME QBluetooth
#define QBT_NAMESPACE_BEGIN	namespace QBT_NAMESPACE_NAME{
#define QBT_NAMESPACE_END	}
#define QBT_USE_NAMESPACE	using namespace QBT_NAMESPACE_NAME;
#else
#define QBT_PREPEND_NAMESPACE(name)	name
#define QBT_NAMESPACE_NAME
#define QBT_NAMESPACE_BEGIN
#define QBT_NAMESPACE_END
#define QBT_USE_NAMESPACE
#endif

#endif // QBTGLOBAL_H


code:
/*
 * QBtServiceAdvertiser.cpp
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "../QBtServiceAdvertiser.h"
#include <QBtAuxFunctions.h>

#if defined(Q_OS_SYMBIAN)
#include "../QBtServiceAdvertiser_symbian.h"
#elif defined(Q_OS_WIN32)
#include "../QBtServiceAdvertiser_win32.h"
#elif !defined(Q_OS_WIN32) && !defined(Q_OS_SYMBIAN)
#include "../QBtServiceAdvertiser_stub.h"
#endif

QBT_NAMESPACE_BEGIN

//////////////////////////////////////////////////
// QBtServiceAdvertiser::QBtServiceAdvertiser()	//
// Defaul constructor							//
//////////////////////////////////////////////////
QBtServiceAdvertiser::QBtServiceAdvertiser(QObject *parent) :
    QObject(parent), _localService(NULL)
{
#ifdef Q_OS_SYMBIAN
    QT_TRAP_THROWING(_implPtr = QBtServiceAdvertiserPrivate::NewL(this));
#else
    _implPtr = new QBtServiceAdvertiserPrivate(this);
#endif
}

QBtServiceAdvertiser::~QBtServiceAdvertiser()
{
    stopAdvertising();

    SafeDelete(_localService);
    SafeDelete(_implPtr);
}

/**
 * startAdvertising(const QBtService& service)
 */
void QBtServiceAdvertiser::startAdvertising(const QBtService& service)
{
    _localService = new QBtService(service);
    _implPtr->StartAdvertiser(service);
}

/**
 * stopAdvertising()
 */
void QBtServiceAdvertiser::stopAdvertising()
{
    _implPtr->StopAdvertiser();
}

/**
 *
 */
void QBtServiceAdvertiser::updateAvailability(bool aAvailable)
{
    _implPtr->UpdateAvailability(aAvailable);
}

QBT_NAMESPACE_END


code:
/*
 * QBtServiceAdvertiser_stub.cpp
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "../QBtServiceAdcertiser_stub.h"

QBtServiceAdvertiserPrivate::QBtServiceAdvertiserPrivate(QBtServiceAdvertiser* publicClass)
	: p_ptr(publicClass)
{
}

QBtServiceAdvertiserPrivate::~QBtServiceAdvertiserPrivate()
{
}

void QBtServiceAdvertiserPrivate::StartAdvertiser(const QBtService& service)
{
	return;
}

void QBtServiceAdvertiserPrivate::StopAdvertiser()
{
	return;
}

void QBtServiceAdvertiserPrivate::UpdateAvailability(TBool aAvailable)
{
	return;
}


code:
/*
 * QBtServiceAdvertiser_symbian.cpp
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <btmanclient.h>
#include "../QBtServiceAdvertiser_symbian.h"
#include <QBtAuxFunctions.h>

QBtServiceAdvertiserPrivate* QBtServiceAdvertiserPrivate::NewL(QBtServiceAdvertiser* publicClass)
{
    QBtServiceAdvertiserPrivate* self = QBtServiceAdvertiserPrivate::NewLC(publicClass);
    CleanupStack::Pop(self);
    return self;
}

QBtServiceAdvertiserPrivate* QBtServiceAdvertiserPrivate::NewLC(QBtServiceAdvertiser* publicClass)
{
    QBtServiceAdvertiserPrivate* self = new (ELeave) QBtServiceAdvertiserPrivate(publicClass);
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
}

void QBtServiceAdvertiserPrivate::ConstructL()
{
}

// ----------------------------------------------------------------------------
// QBtServiceAdvertiserPrivate::QBtServiceAdvertiserPrivate(QBtServiceAdvertiser* publicClass)
//
// constructor
// ----------------------------------------------------------------------------
QBtServiceAdvertiserPrivate::QBtServiceAdvertiserPrivate(QBtServiceAdvertiser* publicClass)
      : /*localService(NULL),*/ p_ptr(publicClass)
{
}

// ----------------------------------------------------------------------------
// QBtServiceAdvertiserPrivate::~QBtServiceAdvertiserPrivate()
//
// destructor
// ----------------------------------------------------------------------------
QBtServiceAdvertiserPrivate::~QBtServiceAdvertiserPrivate()
{
    TRAPD(err, StopAdvertiser());

    //SafeDelete(localService);
}

// ----------------------------------------------------------------------------
// QBtServiceAdvertiserPrivate::StartAdvertiser(const QBtService& service)
//
// start service advertiser on given channel.  an entry to service discovery
// database will be entered describing our advertised service.
// ----------------------------------------------------------------------------
void QBtServiceAdvertiserPrivate::StartAdvertiser (const QBtService& service)
{
   //localService = new QBtService(service);

   // open sdp session
   User::LeaveIfError(iSdp.Connect());

   // open sdp database session
   User::LeaveIfError(iSdpDB.Open(iSdp));

   // create a record of the correct service class
   //QBtUuid uuid = service.getClass();

   TUUID uuid = QBtUuidToSymbianUuid (service.getClass() );
   iSdpDB.CreateServiceRecordL (uuid, iRecord);

   // add a protocol to the record
   CSdpAttrValueDES* protocolDescriptorList = CSdpAttrValueDES::NewDESL(NULL);
   CleanupStack::PushL(protocolDescriptorList);

   TBuf8<1> channel;
   channel.Append((TChar)service.getPort());

   // create protocol list for our service
   MSdpElementBuilder* e = protocolDescriptorList->StartListL();

      QBtService::ProtocolList protocolList = service.getProtocols();
      for (int i=0; i < protocolList.size(); i++)
      {
         e = e->BuildDESL();
         e = e->StartListL();

            TUUID u = QBtUuidToSymbianUuid (protocolList[i]);
            e = e->BuildUUIDL (u);

            if (u == TUUID (KRFCOMM) )
               e = e->BuildUintL(channel);

         e = e->EndListL();
       }

   e->EndListL();

   // set protocol list to the record
   iSdpDB.UpdateAttributeL(iRecord, KSdpAttrIdProtocolDescriptorList,
         *protocolDescriptorList);
   CleanupStack::PopAndDestroy(protocolDescriptorList);

   // add a name to the record
   TPtrC16 servName(service.getName().utf16());

   iSdpDB.UpdateAttributeL(iRecord,
         KSdpAttrIdBasePrimaryLanguage +
         KSdpAttrIdOffsetServiceName,
         servName);

   // add a description to the record
   TPtrC16 servDescr(service.getDescription().utf16());

   iSdpDB.UpdateAttributeL(iRecord,
         KSdpAttrIdBasePrimaryLanguage +
         KSdpAttrIdOffsetServiceDescription,
         servDescr);

   // set service available
   UpdateAvailability(ETrue);

   // notify
   QT_TRYCATCH_LEAVING (emit p_ptr->advertisingStarted(service) );

}

// ----------------------------------------------------------------------------
// QBtServiceAdvertiserPrivate::StopAdvertiser()
//
// stop service advertiser.  delete service record from service discovery
// database to stop advertising.
// ----------------------------------------------------------------------------
void QBtServiceAdvertiserPrivate::StopAdvertiser()
{
    if ( iRecord!=0 )
    {
        // delete out record from service discovery database
        iSdpDB.DeleteRecordL(iRecord);

        // close sdp and sdp db sessions
        iSdpDB.Close();
        iSdp.Close();
        iRecord=0;

        //
        QT_TRYCATCH_LEAVING (emit p_ptr->advertisingStopped() );
    }

}

// ----------------------------------------------------------------------------
// QBtServiceAdvertiserPrivate::UpdateAvailability(TBool aAvailable)
//
// set availability of our advertised service.  the service record on the
// service discovery database will be updated accordingly.
// ----------------------------------------------------------------------------
void QBtServiceAdvertiserPrivate::UpdateAvailability(TBool aAvailable)
{
    TInt state = aAvailable ? 0xFF : 0x00;
    // set availability
    iSdpDB.UpdateAttributeL(iRecord, KSdpAttrIdServiceAvailability, state);
    // mark record changed
    iSdpDB.UpdateAttributeL(iRecord, KSdpAttrIdServiceRecordState,
            ++iRecordState);
}


code:
/*
 * QBtServiceAdvertiser_stub.cpp
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "../QBtServiceAdvertiser_win32.h"

QBT_NAMESPACE_BEGIN

QBtServiceAdvertiserPrivate::QBtServiceAdvertiserPrivate(QBtServiceAdvertiser* publicClass)
	: p_ptr(publicClass)
{
}

QBtServiceAdvertiserPrivate::~QBtServiceAdvertiserPrivate()
{
}

void QBtServiceAdvertiserPrivate::StartAdvertiser(const QBtService& /*service*/)
{
	emit p_ptr->error(QBtServiceAdvertiser::FeatureNotSupported);
	return;
}

void QBtServiceAdvertiserPrivate::StopAdvertiser()
{
    emit p_ptr->error(QBtServiceAdvertiser::FeatureNotSupported);
	return;
}

void QBtServiceAdvertiserPrivate::UpdateAvailability(bool /*aAvailable*/)
{
	emit p_ptr->error(QBtServiceAdvertiser::FeatureNotSupported);
	return;
}

QBT_NAMESPACE_END


code:
/*
 * QBtServiceAdvertiser.h
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef QBTSERVICEADVERTISER_H_
#define QBTSERVICEADVERTISER_H_

#include <QBtGlobal.h>
#include <QtCore/QObject>
#include <QBtTypes.h>

QBT_NAMESPACE_BEGIN

//forward declaration
class QBtServiceAdvertiserPrivate;

/**
 * Class responsible to advertise a given bluetooth service.
 *
 * After the instantiation of the class, startAdvertising(const QBtService&) can be callled
 * to start advertising the given bluetooth service. If successfull then
 * advertisingStarted(const QBtService&) signal is emitted.
 *
 * At any time stopAdvertising() can be called to stop the advertising and remove the
 * registered service from the SDP database. If successfull then advertisingStopped()
 * is emitted.
 *
 * If user wants to temporarily deactive the service advertisement then he can call
 * updateAvailability(bool) (instead of the stopAdvertising() that stops the advertising
 * permanently).
 *
 * In case of error, error(ErrorCodes) signal is emitted.
 *
 * For integrity reasons, at destruction stops the advertising
 * causing the service to be deleted from the SDP database.
 *
 * NOTE: Currently there is no implementation on the Windows platform so
 * after the intatiation of this object, any call to any function will
 * emit an error(QBtServiceAdvertiser::FeatureNotSupported) signal.
 */
class DLL_EXPORT QBtServiceAdvertiser : public QObject
{
    Q_OBJECT

public:
    enum ErrorCodes
    {
        FeatureNotSupported
    };

public:
    QBtServiceAdvertiser(QObject* parent);
    ~QBtServiceAdvertiser();

    /**
     * Starts the service advertiser.
     *
     * @param service the service class that contains all the necessery
     * information for transmitting the service
     */
    void startAdvertising(const QBtService& service);

    /**
     * Stops the transmittion of the service running (if any)
     */
    void stopAdvertising();

    /**
     * Change the availability of the service.
     * @param aAvailable If true, the service is transmitted.
     */
    void updateAvailability(bool aAvailable);

signals:
    /**
     * The signal is emitted if the transmittion of the service is started
     * @param service A reference to an object containing all the info of the service being transmitted.
     */
    void advertisingStarted(const QBtService& service);

    /**
     * The signal is emitted when the transmittion of the service ends.
     */
    void advertisingStopped();

    /**
     *
     * Emitted in case of error (not implemented).
     */
    void error (QBtServiceAdvertiser::ErrorCodes code);

private:
    // The service to advertise
    QBtService* _localService;

    //pointer to implementation
    QBtServiceAdvertiserPrivate *_implPtr;

    friend class QBtServiceAdvertiserPrivate;

};

QBT_NAMESPACE_END

//Q_DECLARE_METATYPE(QBT_PREPEND_NAMESPACE(QBtServiceAdvertiser))

#endif /* QBTSERVICEADVERTISER_H_ */


code:
/*
 * QBtServiceAdvertiser_stub.h
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef QBTSERVICEADVERTISER_STUB_H_
#define QBTSERVICEADVERTISER_STUB_H_

class QBtServiceAdvertiserPrivate
{
public:
	QBtServiceAdvertiserPrivate(QBtServiceAdvertiser* publicClass);
	~QBtServiceAdvertiserPrivate();

	/*!
	 * StartAdvertiser(const QBtService& service)
	 *
	 * Starts the service advertiser.
	 *
	 * param service the service class that contains all the necessery
	 * information for transmitting the service
	 */
	void StartAdvertiser(const QBtService& service);

	/*!
	 * StopAdvertiser()
	 *
	 * Stops the service advertiser.  our entry from service
	 * discovery database will be removed.
	 */
	void StopAdvertiser();

	/*!
	 * UpdateAvailability()
	 *
	 * Updates the availability of advertised service.  the service
	 * record in service discovery database will be updated accordingly.
	 *
	 * param aAvailable true if the service should be set as available,
	 * false if unavailable.
	 */
	void UpdateAvailability(TBool aAvailable);

private:
	QBtServiceAdvertiser* p_ptr;
};

#endif /* QBTSERVICEADVERTISER_STUB_H_ */


code:
/*
 * QBtServiceAdvertiser_symbian.h
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef QBTSERVICEADVERTISER_SYMBIAN_H_
#define QBTSERVICEADVERTISER_SYMBIAN_H_

// INCLUDES
#include <e32base.h>

#include <coecntrl.h>
#include <es_sock.h>
#include <btdevice.h>
#include <bt_sock.h>
#include <btsdp.h>
#include <btmanclient.h>

#include <QBtTypes.h>
#include <QBtServiceAdvertiser.h>

class QBtServiceAdvertiserPrivate  : public CBase
{
public:
    /*!
     * NewL(QBtServiceAdvertiser* publicClass)
     *
     * Create new QBtServiceAdvertiserPrivate object
     * return a pointer to the created instance of QBtServiceAdvertiserPrivate
     */
    static QBtServiceAdvertiserPrivate* NewL(QBtServiceAdvertiser* publicClass);

    /*!
     * NewLC(QBtServiceAdvertiser* publicClass)
     *
     */
    static QBtServiceAdvertiserPrivate* NewLC(QBtServiceAdvertiser* publicClass);

    /*!
     * ~CDeviceDiscoverer()
     *
     * Destroy the object and release all memory objects
     */
    ~QBtServiceAdvertiserPrivate();

    /*!
     * StartAdvertiser(const QBtService& service)
     *
     * Starts the service advertiser.
     *
     * param service the service class that contains all the necessery
     * information for transmitting the service
     */
    void StartAdvertiser(const QBtService& service);

    /*!
     * StopAdvertiser()
     *
     * Stops the service advertiser.  our entry from service
     * discovery database will be removed.
     */
    void StopAdvertiser();

    /*!
     * UpdateAvailability()
     *
     * Updates the availability of advertised service.  the service
     * record in service discovery database will be updated accordingly.
     *
     * param aAvailable true if the service should be set as available,
     * false if unavailable.
     */
    void UpdateAvailability(TBool aAvailable);

private:

    /*!
     * QBtServiceAdvertiserPrivate(QBtServiceAdvertiser* publicClass)
     *
     * Perform the first phase of two phase construction
     */
    QBtServiceAdvertiserPrivate(QBtServiceAdvertiser* publicClass);

    /*!
     * ConstructL()
     *
     */
    void ConstructL();

private:

    // service discovery protocol session
    RSdp iSdp;
    // service discovery database (sdp)
    RSdpDatabase iSdpDB;
    // service record
    TSdpServRecordHandle iRecord;
    // service record state
    TInt iRecordState;

    // local service to advertise
    //QBtService* localService;

    //pointer to parent object (from constructor). Not owned by this class
    QBtServiceAdvertiser *p_ptr;
};

#endif /* QBTSERVICEADVERTISER_SYMBIAN_H_ */


code:
/*
 * QBtServiceAdvertiser_stub.h
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef QBTSERVICEADVERTISER_STUB_H_
#define QBTSERVICEADVERTISER_STUB_H_

#include <QBtServiceAdvertiser.h>
#include <QBtAuxFunctions.h>

QBT_NAMESPACE_BEGIN

class QBtServiceAdvertiserPrivate
{
public:
    QBtServiceAdvertiserPrivate(QBtServiceAdvertiser* publicClass);
    ~QBtServiceAdvertiserPrivate();

    /*!
     * StartAdvertiser(const QBtService& service)
     *
     * Starts the service advertiser.
     *
     * param service the service class that contains all the necessery
     * information for transmitting the service
     */
    void StartAdvertiser(const QBtService& service);

    /*!
     * StopAdvertiser()
     *
     * Stops the service advertiser.  our entry from service
     * discovery database will be removed.
     */
    void StopAdvertiser();

    /*!
     * UpdateAvailability()
     *
     * Updates the availability of advertised service.  the service
     * record in service discovery database will be updated accordingly.
     *
     * param aAvailable true if the service should be set as available,
     * false if unavailable.
     */
    void UpdateAvailability(bool aAvailable);

private:
    QBtServiceAdvertiser* p_ptr;
};

QBT_NAMESPACE_END

#endif /* QBTSERVICEADVERTISER_STUB_H_ */


code:
/*
 * QBtServiceDiscoverer.cpp
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "../QBtServiceDiscoverer.h"
#include <QBtAuxFunctions.h>

#if defined(Q_OS_SYMBIAN)
#include "../QBtServiceDiscoverer_symbian.h"
#elif defined(Q_OS_WIN32)
#include "../QBtServiceDiscoverer_win32.h"
#elif !defined(Q_OS_WIN32) && !defined(Q_OS_SYMBIAN)
#include "../QBtServiceDiscoverer_stub.h"
#endif

QBT_NAMESPACE_BEGIN

//____________________________________________________________________________

QBtServiceDiscoverer::QBtServiceDiscoverer(QObject *parent) :
    QObject(parent)
{
#ifdef Q_OS_SYMBIAN
    QT_TRAP_THROWING(_implPtr = QBtServiceDiscovererPrivate::NewL(this));
#else
    _implPtr = new QBtServiceDiscovererPrivate(this);
#endif
}

//____________________________________________________________________________

QBtServiceDiscoverer::~QBtServiceDiscoverer()
{
    SafeDelete(_implPtr);
}

//____________________________________________________________________________

void QBtServiceDiscoverer::startDiscovery (const QBtDevice& targetDevice)
{
    _remoteDevice = targetDevice;
    _implPtr->DiscoverServices (& _remoteDevice);
}

//____________________________________________________________________________

void QBtServiceDiscoverer::startObexDiscovery (const QBtDevice& targetDevice)
{
    _remoteDevice = targetDevice;
    _implPtr->DiscoverObexServices (& _remoteDevice);
}

//____________________________________________________________________________

void QBtServiceDiscoverer::startRfcommDiscovery (const QBtDevice& targetDevice)
{
    _remoteDevice = targetDevice;
    _implPtr->DiscoverRfcommServices (& _remoteDevice);
}

//____________________________________________________________________________

void QBtServiceDiscoverer::startDiscovery (const QBtDevice& targetDevice, const QBtUuid & uuid)
{
    _remoteDevice = targetDevice;
    _implPtr->DiscoverSpecificClass (& _remoteDevice, uuid);//(QBtConstants::ServiceClass)uuid.get());
}

//____________________________________________________________________________

void QBtServiceDiscoverer::startDiscovery (const QBtDevice& targetDevice, const QList<QBtUuid> & uuids)
{
    _remoteDevice = targetDevice;
    _implPtr->DiscoverSpecificClasses (& _remoteDevice, uuids);
}

//____________________________________________________________________________

void QBtServiceDiscoverer::stopDiscovery()
{
    _implPtr->StopDiscovery();
}

//____________________________________________________________________________

const QBtDevice & QBtServiceDiscoverer::getTargetDevice() const
{
    return _remoteDevice;
}

//____________________________________________________________________________

QBtService::List QBtServiceDiscoverer::getInquiredServices()
{
    return _remoteDevice.getSupportedServices();
}

//____________________________________________________________________________

bool QBtServiceDiscoverer::isBusy () const
{
	return _implPtr->IsBusy();
}

QBT_NAMESPACE_END


code:
/*
 * QBtServiceDiscovererForAll.cpp
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "../QBtServiceDiscovererForAll.h"
#include <QBtAuxFunctions.h>

QBT_NAMESPACE_BEGIN

//____________________________________________________________________________

QBtServiceDiscovererForAll::QBtServiceDiscovererForAll (QObject *parent) :
    QObject(parent)
{
    // service discovery
    connect (&_serviceDiscoverer, SIGNAL (newServiceFound (const QBtDevice &, const QBtService&)), SLOT (sd_newServiceFound (const QBtDevice &, const QBtService&)));
    connect (&_serviceDiscoverer, SIGNAL (discoveryStopped()), SLOT (sd_serviceDiscoveryEnded()) );
    connect (&_serviceDiscoverer, SIGNAL (discoveryStarted()), SLOT (sd_serviceDiscoveryStarted()) );
    connect (&_serviceDiscoverer, SIGNAL (error (QBtServiceDiscoverer::ServiceDiscoveryError)), SLOT(sd_error (QBtServiceDiscoverer::ServiceDiscoveryError)) );

    // device discovery
    connect (&_deviceDiscoverer, SIGNAL(discoveryStopped ()), SLOT (dd_discoveryEnded ()) );
    connect (&_deviceDiscoverer, SIGNAL(discoveryStarted ()), SLOT (dd_discoveryStarted ()) );
    connect (&_deviceDiscoverer, SIGNAL(newDeviceFound (const QBtDevice &)), SLOT (dd_newDeviceFound (const QBtDevice &)) );
    connect (&_deviceDiscoverer, SIGNAL(error(QBtDeviceDiscoverer::DeviceDiscoveryErrors)), SLOT (dd_error(QBtDeviceDiscoverer::DeviceDiscoveryErrors)) );
}

//____________________________________________________________________________

QBtServiceDiscovererForAll::~QBtServiceDiscovererForAll()
{
}

//____________________________________________________________________________

void QBtServiceDiscovererForAll::startDiscovery ()
{
   _targetServices.clear();
   _targetServices.append(QBtUuid (QBtConstants::RFCOMM));
   _targetServices.append(QBtUuid (QBtConstants::OBEX));

   _startDiscovery ();

}

//____________________________________________________________________________

void QBtServiceDiscovererForAll::startObexDiscovery ()
{
   _targetServices.clear();
   _targetServices.append(QBtUuid (QBtConstants::OBEX));

   _startDiscovery();
}

//____________________________________________________________________________

void QBtServiceDiscovererForAll::startRfcommDiscovery ()
{
   _targetServices.clear();
   _targetServices.append(QBtUuid (QBtConstants::RFCOMM));

   _startDiscovery();
}

//____________________________________________________________________________

void QBtServiceDiscovererForAll::startDiscovery (const QBtUuid & uuid)
{
   _targetServices.clear();
   _targetServices.append (uuid);

   _startDiscovery();
}

//____________________________________________________________________________

void QBtServiceDiscovererForAll::startDiscovery (const QList<QBtUuid> & uuids)
{
   _targetServices = uuids;
   _startDiscovery();
}

//____________________________________________________________________________

void QBtServiceDiscovererForAll::_startDiscovery ()
{
   if (isBusy() )
      return;

   //
   _aborted = false;

   //
   _deviceList.clear();

   // start first by discovering devices
   _deviceDiscoverer.startDiscovery();
}

//____________________________________________________________________________

void QBtServiceDiscovererForAll::stopDiscovery()
{
   if (_serviceDiscoverer.isBusy())
    { _serviceDiscoverer.stopDiscovery(); _aborted = true; }

   if (_deviceDiscoverer.isBusy())
    { _deviceDiscoverer.stopDiscovery(); _aborted = true; }

}

//____________________________________________________________________________

void QBtServiceDiscovererForAll::dd_discoveryEnded()
{
   // aborted ?
   if (_aborted)
   {
      emit discoveryEnded();
      return;
   }

   // starting fetching services
   const QBtDevice::List& list = _deviceDiscoverer.getInquiredDevices();
   _deviceIndex = 0;

    if (list.length() > 0)
    {
    BT_DEBUG_MSG("starting service search");

        _serviceDiscoverer.startDiscovery (list [0], _targetServices);
    }
    else
    {
      // no devices found
      emit discoveryEnded();
    }

}

//____________________________________________________________________________

void QBtServiceDiscovererForAll::dd_discoveryStarted()
{
    emit discoveryStarted();
}

//____________________________________________________________________________

void QBtServiceDiscovererForAll::sd_newServiceFound (const QBtDevice &/*targetDevice*/, const QBtService & /*newService*/)
{
}

//____________________________________________________________________________

void QBtServiceDiscovererForAll::sd_serviceDiscoveryStarted ()
{
}

//____________________________________________________________________________

void QBtServiceDiscovererForAll::sd_serviceDiscoveryEnded ()
{
   // was it aborted?
   if (_aborted)
   {
      emit discoveryEnded();
      return;
   }

   // get processed device
   const QBtDevice & device = _serviceDiscoverer.getTargetDevice();

   // let's see what happened, if there are no services, some error might have ocurred
   const QBtService::List & serviceList = device.getSupportedServices();

   // notify and keep if the device has services. If it doesn't have services, it
   // might have turned off bluetooth (or walked away) after it had been discovered
   if (serviceList.isEmpty() == false)
   {
      // notify about this device
      emit newDeviceFound (device);

      // keep this device
      _deviceList.append (device);
   }

   // fetch services for next device
   const QBtDevice::List& list = _deviceDiscoverer.getInquiredDevices();
   _deviceIndex++;

    if (_deviceIndex < list.length() )
    {
        _serviceDiscoverer.startDiscovery (list [_deviceIndex], _targetServices);
    }
    else
    {
        // service discovery ended
        emit discoveryEnded();
    }

}

//____________________________________________________________________________

void QBtServiceDiscovererForAll::sd_error (QBtServiceDiscoverer::ServiceDiscoveryError error)
{
    BT_DEBUG_MSG (QString("<service discovery error: %1>").arg(error) );
    emit serviceDiscoveyError (_serviceDiscoverer.getTargetDevice(), error);

}

//____________________________________________________________________________

void QBtServiceDiscovererForAll::dd_error(QBtDeviceDiscoverer::DeviceDiscoveryErrors error)
{
   BT_DEBUG_MSG (QString("<device discovery error: %1>").arg(error) );
   emit deviceDiscoveryError (error);
}

//____________________________________________________________________________

void QBtServiceDiscovererForAll::dd_newDeviceFound (const QBtDevice& /*remoteDevice*/)
{}

//____________________________________________________________________________

int QBtServiceDiscovererForAll::getNumberOfFoundDevices() const
{
    return _deviceList.length();
}

//____________________________________________________________________________

bool QBtServiceDiscovererForAll::foundDevices () const
{
   return _deviceList.length() != 0;
}

//____________________________________________________________________________

const QBtDevice::List & QBtServiceDiscovererForAll::getDeviceList() const
{
    return _deviceList;
}

//____________________________________________________________________________

bool QBtServiceDiscovererForAll::isBusy () const
{
    return (_deviceDiscoverer.isBusy() || _serviceDiscoverer.isBusy() );
}

QBT_NAMESPACE_END


code:
/*
 * QBtServiceDiscoverer_stub.cpp
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "../QBtServiceDiscoverer_stub.h"

QBtServiceDiscovererPrivate::QBtServiceDiscovererPrivate(QBtServiceDiscoverer* publicClass):
	p_ptr(publicClass)
{
}

QBtServiceDiscovererPrivate::~QBtServiceDiscovererPrivate()
{
}

void QBtServiceDiscovererPrivate::DiscoverServicesOnDevice(QBtDevice* targetDevice)
{
	return;
}

void QBtServiceDiscovererPrivate::DiscoverSpecificProtocol(
			QBtDevice* targetDevice, QBtConstants::ServiceClass uuid)
{
	return;
}

void QBtServiceDiscovererPrivate::StopDiscovery()
{
	return;
}

QBtService::List QBtServiceDiscovererPrivate::GetSupportedServices()
{
	return QBtService::List();
}

bool QBtServiceDiscovererPrivate::IsBusy()
{
	return false;
}


code:
/*
 * QBtServiceDiscoverer_symbian.cpp
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "../QBtServiceDiscoverer_symbian.h"
#include "../../QBtAuxFunctions.h"
#include <btsdp.h>
#include <e32des8.h>

#include <QMessageBox>

// debug aid
inline void MSG(const QString & m)
{ qDebug() << m; }

//____________________________________________________________________________

QBtServiceDiscovererPrivate* QBtServiceDiscovererPrivate::NewL(QBtServiceDiscoverer* publicClass)
{
	QBtServiceDiscovererPrivate* self = QBtServiceDiscovererPrivate::NewLC(publicClass);
	CleanupStack::Pop(self);
	return self;
}

//____________________________________________________________________________

QBtServiceDiscovererPrivate* QBtServiceDiscovererPrivate::NewLC(QBtServiceDiscoverer* publicClass)
{
	QBtServiceDiscovererPrivate* self = new (ELeave) QBtServiceDiscovererPrivate(publicClass);
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
}

//____________________________________________________________________________

void QBtServiceDiscovererPrivate::ConstructL()
{}

//____________________________________________________________________________

QBtServiceDiscovererPrivate::QBtServiceDiscovererPrivate (QBtServiceDiscoverer* publicClass)
    : _agent(0),
      _searchPattern(0),
      _parent_ptr(publicClass),
      _discoveryInProgress (false)
{}

//____________________________________________________________________________

QBtServiceDiscovererPrivate::~QBtServiceDiscovererPrivate()
{
	// must not throw/leave
    //TRAPD (error, StopDiscovery() );
    TRAPD (error, FinishDiscovery() );
}

//____________________________________________________________________________

void QBtServiceDiscovererPrivate::FinishDiscovery()
{
   if (_discoveryInProgress == false)
      return;

   _discoveryInProgress = false;

   if (_agent)
   {
      _agent->Cancel();
      delete _agent;
      _agent = 0;
   }

   if (_searchPattern)
   {
      _searchPattern->Reset();
      delete _searchPattern;
      _searchPattern= 0;
   }

}

//____________________________________________________________________________

void QBtServiceDiscovererPrivate::PrepareSearch (QBtDevice* targetDevice)
{
   _targetDevice = targetDevice;

   _uuidList.clear();
   _serviceList.clear();
   _serviceUuidsFound.clear();
}

//____________________________________________________________________________

void QBtServiceDiscovererPrivate::DiscoverObexServices (QBtDevice* _targetDevice)
{
   PrepareSearch (_targetDevice);

   _uuidList.append(QBtUuid (QBtConstants::OBEX));
   _DiscoverSpecificClass (_uuidList [0]);
}

//____________________________________________________________________________

void QBtServiceDiscovererPrivate::DiscoverRfcommServices (QBtDevice* _targetDevice)
{
   PrepareSearch (_targetDevice);

   _uuidList.append(QBtUuid (QBtConstants::RFCOMM));
   _DiscoverSpecificClass (_uuidList [0]);
}

//____________________________________________________________________________

void QBtServiceDiscovererPrivate::DiscoverServices (QBtDevice* _targetDevice)
{
   PrepareSearch (_targetDevice);

   _uuidList.append(QBtUuid (QBtConstants::RFCOMM));
   _uuidList.append(QBtUuid (QBtConstants::OBEX));

   _DiscoverSpecificClass (_uuidList [0]);
}

//____________________________________________________________________________

void QBtServiceDiscovererPrivate::DiscoverSpecificClasses (QBtDevice* _targetDevice, const QList<QBtUuid> & uuids)
{
   BT_ASSERT_MSG (uuids.length() > 0, "empty uuid list");

   PrepareSearch (_targetDevice);

   _uuidList = uuids;
   _DiscoverSpecificClass (_uuidList [0]);
}

//____________________________________________________________________________

void QBtServiceDiscovererPrivate::DiscoverSpecificClass (QBtDevice* _targetDevice, const QBtUuid & uuid)
{
   BT_ASSERT_MSG (uuid.isNull() == false, "empty uuid");

   PrepareSearch (_targetDevice);

   _uuidList.append(uuid);
   _DiscoverSpecificClass (_uuidList [0]);
}

//____________________________________________________________________________
//
// discover a given services on given device.  a service discovery agent will be
// started to do the discovery of services on given remote device which
// match to the given uuid

void QBtServiceDiscovererPrivate::_DiscoverSpecificClass (const QBtUuid & uuid)
{
   // end current discovery of any
   FinishDiscovery();

   // toggle guard, setup
   _discoveryInProgress = true;

   // get symbian addr
   const TBTDevAddr devAddress = _targetDevice->getAddress().convertToSymbianBtDevAddr();

   // init new service discovery agent
   _agent = CSdpAgent::NewL( *this, devAddress);

   // set search properties for agent
   _searchPattern = CSdpSearchPattern::NewL();

   // use our service id to filter the services discovered
   // -> will return only the services with matching service id(s)
   TUUID u = QBtUuidToSymbianUuid (uuid);
   _searchPattern->AddL (u);

   // add filter
   _agent->SetRecordFilterL (*_searchPattern);

   // initiate search
   // this will result in call to NextRecordRequestComplete()
   _agent->NextRecordRequestL();

}

//____________________________________________________________________________
//
// called when the service discovery agent has completed discovering services
// on device.  now the attributes of the found service records (if any) must
// be evaluated.  if no service records were discovered, proceed doing
// service discovery on next device.

void QBtServiceDiscovererPrivate::NextRecordRequestComplete (TInt aError,  TSdpServRecordHandle aHandle, TInt aTotalRecordsCount)
{

   // is this query over?
   if (aError == KErrEof || aTotalRecordsCount == 0)
   {
      ProcessNextService();
      return;
   }

   // an error ocurred?
   if (aError != KErrNone)
   {
      BT_DEBUG_MSG(QString("[ERROR: %1").arg(aError));

      //discovering new service on target device
      QT_TRYCATCH_LEAVING (emit _parent_ptr->error(QBtServiceDiscoverer::ServiceDiscoveryNotAbleToComplete) );

      //emit _parent_ptr->discoveryStopped("Error-ServiceDiscoveryNotAbleToComplete");
      QT_TRYCATCH_LEAVING(emit _parent_ptr->discoveryStopped() );

      _discoveryInProgress = false;
      return;
   }

   // new entry for service record
   _serviceRecords [aHandle] = ServiceRecord();

   // go for first attribute
   ServiceRecord & record = _serviceRecords [aHandle];
   TRAPD (err, _agent->AttributeRequestL(aHandle, record.attributesToProcess.first() ) );

}

//____________________________________________________________________________
//
// called when the service attributes for the service record have been
// retrieved.

void QBtServiceDiscovererPrivate::AttributeRequestResult (TSdpServRecordHandle aHandle,
                                                          TSdpAttributeID id,
                                                          CSdpAttrValue* aAttrValue)
{
   BT_ASSERT_MSG (_serviceRecords.contains(aHandle), "service not in the map");
   ServiceRecord & record = _serviceRecords [aHandle];

   switch (id)
   {
      case KSdpAttrIdProtocolDescriptorList:
      {
         record.protocols.reset();
         aAttrValue->AcceptVisitorL (record.protocols);

      } break;

      case KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceName:
      {
         record.name.reset();
         aAttrValue->AcceptVisitorL (record.name);

      } break;

      /*
      case KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceDescription:
      {
         serviceDescriptionVisitor.prepareToRun();
            aAttrValue->AcceptVisitorL (serviceDescriptionVisitor);
         serviceDescriptionVisitor.setFinished();

         serviceDescriptionVisitor.print();

         delete aAttrValue;

      } break;
      */

      case KSdpAttrIdServiceClassIDList:
      {
         record.uuid.reset();
         aAttrValue->AcceptVisitorL (record.uuid);

      } break;

      default:
      {
         BT_ASSERT_MSG2(false, "unexpected attribute", QString::number(id, 16));
      }

   }

   delete aAttrValue;
}

//____________________________________________________________________________
//
// called when the request to resolve the service attributes for the service
// record completes.  if there are more service records, proceed resolving
// the next service record.

void QBtServiceDiscovererPrivate::AttributeRequestComplete (TSdpServRecordHandle aHandle, TInt aError)
{
   if (aError != KErrNone)
   {
      //QT_TRYCATCH_LEAVING (emit _parent_ptr->error(QBtServiceDiscoverer::ProblemAcquiringNextServiceAttributes) );
      MSG (QString ("<Error> %1").arg(aError) );
      return;
   }

   // get current record
   BT_ASSERT_MSG (_serviceRecords.contains(aHandle), "record not in the map");
   ServiceRecord & record = _serviceRecords [aHandle];

   // discard processed attribute (even if it's empty, as in the case of jumping from AttributeRequestL to AttributeRequestComplete
   record.attributesToProcess.pop_front();

   // if complete, fill, notify and go to the next one
   if (record.attributesToProcess.isEmpty() )
   {
      // check if the service was already found
      QString uuid = record.getUuid().toString();

      if (_serviceUuidsFound.contains (uuid) == false)
      {
         // keep it for the record
         _serviceUuidsFound.insert (uuid);

         // save service
         QBtService service;
         service.setHandle    (aHandle);
         service.setClass     (record.getUuid() );
         service.setName      (record.getName() );
         service.setProtocols (record.getProtocols() );
         service.setPort      (record.getPort());
         _serviceList.append (service);

         QT_TRYCATCH_LEAVING (emit _parent_ptr->newServiceFound (*_targetDevice, service) );
      }
      else
      {
         // duplicate service
      }

      // done with attributes for this record, request next
      TRAPD (err, _agent->NextRecordRequestL());
  }
  else
  {
      // process remaining attributes
      TSdpAttributeID id = record.attributesToProcess.first();

      TRAPD (err,_agent->AttributeRequestL (aHandle, id) );

      if (err != KErrNone)
         { MSG (QString ("<Error-AttributeRequestL> %1").arg(err) ); }
  }
}

void QBtServiceDiscovererPrivate::ProcessNextService()
{
   // discard processed uid
   _uuidList.pop_front();

   if (_uuidList.isEmpty() == false)
   {
      _DiscoverSpecificClass (_uuidList [0]);
   }
   else
   {
      // save service list
      _targetDevice->setSupportedServices (_serviceList);

      // no more uuids to process, finish discovery
      FinishDiscovery();

      // notify
      QT_TRYCATCH_LEAVING (emit _parent_ptr->discoveryStopped() );
   }
}

//____________________________________________________________________________

bool QBtServiceDiscovererPrivate::IsBusy() const
{
    return _discoveryInProgress;
}

//____________________________________________________________________________
//
// stop discovering services, stop service discovery agent.

void QBtServiceDiscovererPrivate::StopDiscovery()
{
    if (!_discoveryInProgress)
        return;

   FinishDiscovery();

   // notify
   QT_TRYCATCH_LEAVING (emit _parent_ptr->discoveryStopped() );
}

//____________________________________________________________________________
void ProtocolListVisitor::print()
{
   QString p = "{ProtocolListVisitor} ";
   for (int i = 0; i < _protocols.length(); ++i)
   {
      p += _protocols[i].toString();
      p += " ";
   }

   MSG (QString ("%1 (%2) port: %3").arg (p).arg(_protocols.length() ).arg(_port) );
}

//____________________________________________________________________________
void ProtocolListVisitor::VisitAttributeValueL (CSdpAttrValue &aValue, TSdpElementType aType)
{
   switch (aType)
   {
      case ETypeUUID:
      {
         TPtrC8 uuid(aValue.UUID().ShortestForm());

         // build string
         QString u;
         for (int i = 0; i < uuid.Length(); ++i)
         {
            u += QString ("%1").arg (uuid[i], 2, 16, QLatin1Char('0') );
         }

         // keep
         _protocols.append(QBtUuid (u) );
        break;
      }
      case ETypeUint:
          {
             _port = aValue.Uint();
            break;
          }
      default:
       // rest don't really matter..
      break;
   }
}

//____________________________________________________________________________

void StringVisitor::print()
{
   MSG (QString ("{StringVisitor} %1").arg (_str) );
}

//____________________________________________________________________________

void StringVisitor::VisitAttributeValueL (CSdpAttrValue &aValue, TSdpElementType aType)
{
    switch (aType)
    {
        case ETypeString:
        {
            QString s = QString::fromUtf8( (const char*)aValue.Des().Ptr(), aValue.Des().Length() );
            _str = s;

        } break;

        default:
          break;
    }

}

//____________________________________________________________________________
void ServiceUuidVisitor::print()
{

   QString p = "{ServiceUuidVisitor} ";
   for (int i = 0; i < _uuid.length(); ++i)
   {
      p += _uuid[i].toString();
      p += " ";
   }

   MSG (p);
}

//____________________________________________________________________________

void ServiceUuidVisitor::VisitAttributeValueL (CSdpAttrValue &aValue, TSdpElementType aType)
{
    switch (aType)
    {
      case ETypeUUID:
      {
         TPtrC8 uuid(aValue.UUID().Des());

         QString u;
         for (int i = 0; i < uuid.Length(); ++i)
         {
            u += QString ("%1").arg (uuid[i], 2, 16, QLatin1Char('0') );
         }

         _uuid.append(QBtUuid (u) );

        } break;

        default:
        {
            // rest don't really matter..
            break;
        }
    }
}


code:
/*
 * QBtServiceDiscoverer_stub.cpp
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <QtGlobal>
#include "../QBtServiceDiscoverer_win32.h"

QBT_NAMESPACE_BEGIN

QBtServiceDiscovererPrivate::QBtServiceDiscovererPrivate(QBtServiceDiscoverer* publicClass):
	QObject(NULL), p_ptr(publicClass), isBusy(false)
{
	Construct();
}

void QBtServiceDiscovererPrivate::Construct()
{
	QBtAuxFunctions::InitBthSdk();

	connect(p_ptr, SIGNAL(discoveryStarted()),
			this, SLOT(SetBusy()));
	connect(p_ptr, SIGNAL(discoveryStopped()),
			this, SLOT(SetNotBusy()));
}

QBtServiceDiscovererPrivate::~QBtServiceDiscovererPrivate()
{
	QBtAuxFunctions::DeinitBthSdk();
}

void QBtServiceDiscovererPrivate::DiscoverServices(QBtDevice* targetDevice)
{
	BTSVCHDL remoteServiceHandleArray[128] = {0};
	BTUINT32 remoteServiceNumber = 128;

	BTUINT32 result = BTSDK_FALSE;

	BTDEVHDL devHandle = QBtAuxFunctions::GetDeviceHandle(targetDevice->getAddress());

	if(devHandle == BTSDK_INVALID_HANDLE)
	{
		emit p_ptr->error(QBtServiceDiscoverer::UnknownError);
		return;
	}

	emit p_ptr->discoveryStarted();
	int cnt = 0;
	do
	{
		result = Btsdk_BrowseRemoteServices(devHandle, remoteServiceHandleArray, &remoteServiceNumber);
		cnt++;
	}while(cnt < 5 && result != BTSDK_OK);

	if(cnt == 5 && result != BTSDK_OK)
	{
		emit p_ptr->error(QBtServiceDiscoverer::UnknownError);
		return;
	}

	// process results
	ProcessFoundServices(remoteServiceHandleArray, remoteServiceNumber, QBtConstants::UndefinedClass);

	emit p_ptr->discoveryStopped();

	return;
}

void QBtServiceDiscovererPrivate::DiscoverSpecificClass(
			QBtDevice* targetDevice, QBtUuid uuid)
{
	BTSVCHDL servicesFound[128] = {0};
	BTUINT32 servicesNumFound = 128;

	QBtConstants::ServiceClass serviceUUID = (QBtConstants::ServiceClass)(uuid.get());

	DiscoverServiceHandles(targetDevice, servicesFound, &servicesNumFound, serviceUUID);

	// process results
	ProcessFoundServices(servicesFound, servicesNumFound, serviceUUID);

	emit p_ptr->discoveryStopped();

	return;
}

void QBtServiceDiscovererPrivate::DiscoverServiceHandles(QBtDevice* targetDevice, BTSVCHDL* servicesFound, BTUINT32* servicesNumFound, QBtConstants::ServiceClass uuid)
{
	BtSdkSDPSearchPatternStru sdpStru;
	sdpStru.mask = BTSDK_SSPM_UUID16;
	sdpStru.uuid.Data1 = uuid;

	BTDEVHDL devHandle = QBtAuxFunctions::GetDeviceHandle(targetDevice->getAddress());

	if(devHandle == BTSDK_INVALID_HANDLE)
	{
		emit p_ptr->error(QBtServiceDiscoverer::UnknownError);
		return;
	}

	emit p_ptr->discoveryStarted();

	//start searching on a specific device and service
	int tmpCnt = 0;
	BTINT32 result = BTSDK_FALSE;
	do
	{
		result = Btsdk_BrowseRemoteServicesEx(devHandle, &sdpStru, 1, servicesFound, servicesNumFound);
		tmpCnt++;
	}while(tmpCnt < 5 && result != BTSDK_OK);

	if(tmpCnt == 5 && result != BTSDK_OK)
	{
		emit p_ptr->error(QBtServiceDiscoverer::ServiceDiscoveryNotAbleToComplete);
		return;
	}
}

void QBtServiceDiscovererPrivate::DiscoverSpecificClasses(QBtDevice* targetDevice, const QList<QBtUuid> &uuids)
{
	for(int i=0; i<uuids.size(); i++)
		DiscoverSpecificClass(targetDevice, uuids.at(i));
}

void QBtServiceDiscovererPrivate::DiscoverRfcommServices(QBtDevice* targetDevice)
{
	DiscoverSpecificClass(targetDevice, QBtUuid(QBtConstants::SerialPort));
}

void QBtServiceDiscovererPrivate::DiscoverObexServices(QBtDevice* targetDevice)
{
	DiscoverSpecificClass(targetDevice, QBtUuid(QBtConstants::OBEXFileTransfer));
	DiscoverSpecificClass(targetDevice, QBtUuid(QBtConstants::OBEXObjectPush));
}

void QBtServiceDiscovererPrivate::DiscoverSpecificProtocol(
			QBtDevice* /*targetDevice*/, QBtConstants::ServiceProtocol /*uuid*/)
{
	emit p_ptr->error(QBtServiceDiscoverer::NotSupported);
	return;
}

void QBtServiceDiscovererPrivate::StopDiscovery()
{
	return;
}

// private methods

void QBtServiceDiscovererPrivate::ProcessFoundServices(BTSVCHDL* foundServices, int numOfServices, QBtConstants::ServiceClass wantedClass)
{
	BTUINT32 result = BTSDK_FALSE;
	BtSdkRemoteServiceAttrStru serviceInfo;
	serviceInfo.mask = BTSDK_RSAM_SERVICENAME;

	for(int i=0; i<numOfServices; i++)
	{
		result = Btsdk_GetRemoteServiceAttributes(foundServices[i], &serviceInfo);
		if(result != BTSDK_OK)
			return;

		if((QBtConstants::ServiceClass)serviceInfo.service_class != wantedClass )
			continue;

		QBtService newService;
		newService.setHandle(foundServices[i]);
		newService.setName(QString::fromUtf8((const char*)serviceInfo.svc_name));
		newService.setClass(QBtUuid ((QBtConstants::ServiceClass)serviceInfo.service_class));

		if(serviceInfo.service_class == BTSDK_CLS_SERIAL_PORT)
			RetrieveSPPAttributes(&newService, foundServices[i]);

		p_ptr->_remoteDevice.addNewService(newService);
		emit p_ptr->newServiceFound(p_ptr->_remoteDevice, newService);
	}
}

void QBtServiceDiscovererPrivate::RetrieveSPPAttributes(QBtService* currService, BTSVCHDL servHandle)
{
	BTUINT32 result = BTSDK_FALSE;
	BtSdkRmtSPPSvcExtAttrStru infoStructure;
	BtSdkRemoteServiceAttrStru serviceInfo;
	serviceInfo.mask = BTSDK_RSAM_EXTATTRIBUTES;
	serviceInfo.ext_attributes = &infoStructure;

	result = Btsdk_GetRemoteServiceAttributes(servHandle, &serviceInfo);
	if(result != BTSDK_OK)
		return;

	currService->setPort((unsigned int)infoStructure.server_channel);
}

void QBtServiceDiscovererPrivate::SetBusy()
{
	isBusy = true;
}

void QBtServiceDiscovererPrivate::SetNotBusy()
{
	isBusy = false;
}

bool QBtServiceDiscovererPrivate::IsBusy() const
{
	return isBusy;
}

QBT_NAMESPACE_END


code:
/*
 * QBtServiceDiscoverer.h
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef QBTSERVICEDISCOVERER_H_
#define QBTSERVICEDISCOVERER_H_

#include <QBtGlobal.h>
#include <QtCore/QObject>
#include <QBtTypes.h>
#include <QtCore/QList>

QBT_NAMESPACE_BEGIN

//forward declaration
class QBtServiceDiscovererPrivate;

/**
 * This class provides the mechanism to inquire a given device for the bluetooth
 * services it supports.
 *
 * If startDiscovery (const QBtDevice &) is called, then the device is inquired for all
 * the bluetooth services it supports.
 *
 * If user is searching for a specific service then
 * startDiscovery (const QBtDevice &, const QBtUuid &) or
 * startDiscovery (const QBtDevice &, QBtConstants::ServiceProtocol)
 * can be called, according to the information the user already has
 * about the inquired service.
 * After the successful call of these functions, discoveryStarted()
 * signal is emitted.
 *
 * At any of the above cases, a found service is reported through
 * newServiceFound (const QBtDevice &, const QBtService &) signal.
 *
 * If service inquiring stops (either by the user calling stopDiscovery() or by normal termination
 * of the inquiring) then discoveryStopped() signal is emitted.
 *
 * At any time the user can access the found services through
 * getInquiredServices().
 */
class DLL_EXPORT QBtServiceDiscoverer : public QObject
{
    Q_OBJECT

public:
    enum ServiceDiscoveryError
    {
        ServiceDiscoveryNotAbleToComplete,
        UnableToRetrieveServiceAttributes,
        ProblemRequestingNextServiceRecord,
        ProblemAcquiringNextServiceAttributes,
        NotSupported,
        NoDeviceSelected,
        UnknownError
    };

public:
    QBtServiceDiscoverer(QObject* parent = 0);
    virtual ~QBtServiceDiscoverer();

    /**
     *  getInquiredServices()
     *
     *  Returns a service list containing the inquired services (if any)
     */
    QBtService::List getInquiredServices();

    /**
     *  getTargetDevice()
     *
     *  Returns the remote device selected for service discovery.
     *  If "startDiscovery" function (both overloads) was already called
     *  then returns "targetDevice" which was passed as argument
     *  else returns NULL
     */
    const QBtDevice & getTargetDevice() const;

    /**
     * Returns true if a discovery operation is in progress.
     */
    bool isBusy () const;

public slots:

   /**
    * Starts service discovery for OBEX and RFCOMM services.
    * New services found are reported through signal "newServiceFound" or can
    * be acquired through "getInquiredServices" function
    *
    */
   void startDiscovery (const QBtDevice & targetDevice);

   /**
    * Starts service discovery for OBEX services only.
    * New services found are reported through signal "newServiceFound" or can
    * be aquired through "getInquiredServices" function
    *
    */
   void startObexDiscovery (const QBtDevice & targetDevice);

   /**
    * Starts service discovery for RFCOMM services only.
    * New services found are reported through signal "newServiceFound" or can
    * be acquired through "getInquiredServices" function.
    *
    */
   void startRfcommDiscovery (const QBtDevice & targetDevice);

   /**
    * Starts service discovery for the service (or protocol) identified by
    * the uuid parameter.
    * New services found are reported through signal "newServiceFound" or can
    * be acquired through "getInquiredServices" function.
    *
    */
   void startDiscovery (const QBtDevice & targetDevice, const QBtUuid & uuid);

   /**
    *
    * Starts service discovery for UUIDs provided in the list.
    * New services found are reported through signal "newServiceFound" or can
    * be acquired through "getInquiredServices" function.
    *
    */
   void startDiscovery (const QBtDevice& targetDevice, const QList <QBtUuid> & uuids);

   /**
    * Stops service discovery.
    * Services found so far can be acquired using "getInquiredServices" function.
    */
   void stopDiscovery();

signals:

    /**
     * Signal to report that discovery has started. Alternative is error.
     */
    void discoveryStarted();

    /**
     * Signal to report that discovery has stopped (either cancelled or no new devices to detect)
     */
    void discoveryStopped ();

    /**
     * Signaled for every service detected
     * The targetDevice's field "supportedServices" is updated every time
     * this signal is emitted.
     *
     * @param targetDevice The remote device where the service was found
     * @param service	The remote service found
     */
    void newServiceFound (const QBtDevice& targetDevice, const QBtService & service);

    /**
     * Signal to be emitted when error occurs.
     * @param error error code.
     */
    void error (QBtServiceDiscoverer::ServiceDiscoveryError error);

private:
    QBtDevice 					_remoteDevice;
    QBtServiceDiscovererPrivate *_implPtr;

    friend class QBtServiceDiscovererPrivate;
};

QBT_NAMESPACE_END

//Q_DECLARE_METATYPE(QBT_PREPEND_NAMESPACE(QBtServiceDiscoverer))

#endif /* QBTSERVICEDISCOVERER_H_ */


code:
/*
 * QBtServiceDiscoverer.h
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef QBTSERVICEPROBER_H_
#define QBTSERVICEPROBER_H_

#include <QBtGlobal.h>
#include <QtCore/QObject>
#include <QBtTypes.h>
#include <QBtDeviceDiscoverer.h>
#include <QBtServiceDiscoverer.h>

QBT_NAMESPACE_BEGIN

/**
 * This class provides the mechanism to inquire services available on all devices
 * in the vicinity.
 *
 * when startDiscovery() is called (or its variations), it searches for all devices
 * according to the query criteria (the service uuids).
 *
 * When the discovery starts, the discoveryStarted() signal is emitted. Likewise,
 * the signal discoveryEnded() is emitted when the discovery ends. This happens when
 * the inquiry ends normally or through interruption (by calling stopDiscovery() ).
 *
 * After each device is filled with all services, the signal newDeviceFound (const QBtDevice &)
 * is emitted.
 *
 * After the discovery ends, the found device list is accessible through getDeviceList(). If no
 * devices were found, this list is empty.
 */
class DLL_EXPORT QBtServiceDiscovererForAll : public QObject
{
    Q_OBJECT

public:
    QBtServiceDiscovererForAll(QObject* parent = 0);
    virtual ~QBtServiceDiscovererForAll();

    /**
     * Returns the list of found devices. The list is empty if no
     * devices were found.
     */
    const QBtDevice::List & getDeviceList() const;

    /**
     * Returns true if a discovery operation is in progress.
     */
    bool isBusy () const;

    /**
     * Returns the number of total devices found.
     */
    int getNumberOfFoundDevices () const;

   /**
    * Returns true if any device was found.
    */
    bool foundDevices() const;

public slots:

   /**
    * Starts service discovery for OBEX and RFCOMM services.
    * New devices with their services are reported through signal "newDeviceFound".
    */
   void startDiscovery ();

   /**
    * Starts service discovery for OBEX services only.
    * New devices with their services are reported through signal "newDeviceFound".
    *
    */
   void startObexDiscovery ();

   /**
    * Starts service discovery for RFCOMM services only.
    * New devices with their services are reported through signal "newDeviceFound".
    */
   void startRfcommDiscovery ();

   /**
    * Starts service discovery for the service (or protocol) identified by
    * the uuid parameter.
    * New devices with their services are reported through signal "newDeviceFound".
    */
   void startDiscovery (const QBtUuid & uuid);

   /**
    *
    * Starts service discovery for UUIDs provided in the list.
    * New devices with their services are reported through signal "newDeviceFound".
    */
   void startDiscovery (const QList <QBtUuid> & uuids);

   /**
    * Stops service discovery.
    * Services found so far can be acquired using "getInquiredServices" function.
    */
   void stopDiscovery();

signals:

   /**
    * Signal to report that discovery has started.
    */
   void discoveryStarted();

   /**
    * Signal to report that discovery has ended (either cancelled or no new devices to detect)
    */
   void discoveryEnded ();

   /**
   * Signal to report that the class finished searching for services
   * in the specified device.
   */
   void newDeviceFound (const QBtDevice & device);

   /**
    * Signal emitted when service discovery error occurs when searching for services in the
    * specified device.
    */
   void serviceDiscoveyError (const QBtDevice & device, QBtServiceDiscoverer::ServiceDiscoveryError error);

   /**
    * Signal emitted when device discovery error occurs.
    */
   void deviceDiscoveryError (QBtDeviceDiscoverer::DeviceDiscoveryErrors error);

private slots:

   void sd_newServiceFound (const QBtDevice &targetDevice, const QBtService & service);
   void sd_serviceDiscoveryStarted ();
   void sd_serviceDiscoveryEnded ();
   void sd_error (QBtServiceDiscoverer::ServiceDiscoveryError error);

   //
   void dd_discoveryEnded ();
   void dd_discoveryStarted ();
   void dd_newDeviceFound (const QBtDevice & remoteDevice);
   void dd_error (QBtDeviceDiscoverer::DeviceDiscoveryErrors error );

private:

   void _startDiscovery ();

private:

    QBtDeviceDiscoverer    _deviceDiscoverer;
    QBtServiceDiscoverer   _serviceDiscoverer;
    QList<QBtUuid>         _targetServices;

    QList <QBtDevice>      _deviceList;

    int                    _deviceIndex;
    bool                   _aborted;

};

QBT_NAMESPACE_END

#endif /* QBTSERVICEDISCOVERER_H_ */


code:
/*
 * QBtServiceDiscoverer_stub.h
 *
 *
 *      Author: Ftylitakis Nikolaos
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef QBTSERVICEDISCOVERER_STUB_H_
#define QBTSERVICEDISCOVERER_STUB_H_

#include <QBtDevice.h>
#include <QBtServiceDiscoverer.h>

class QBtServiceDiscovererPrivate
{
public:
    QBtServiceDiscovererPrivate(QBtServiceDiscoverer* publicClass);
    ~QBtServiceDiscovererPrivate();

    void DiscoverServicesOnDevice(QBtDevice* targetDevice);
    void DiscoverSpecificProtocol(QBtDevice* targetDevice, QBtConstants::ServiceClass uuid);
    void StopDiscovery();
    QBtService::List GetSupportedServices();

    bool IsBusy() const;

private:
    QBtServiceDiscoverer* p_ptr;  //Pointer to public interface
};

#endif /* QBTSERVICEDISCOVERER_STUB_H_ */