code:
/*
 * QBtSerialPortServer.cpp
 *
 *
 *      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.
 */

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

#if defined(Q_OS_SYMBIAN)
#include "../QBtSerialPortServer_symbian.h"
#elif defined(Q_OS_WIN32)
#include "../QBtSerialPortServer_win32.h"
#elif !defined(Q_OS_WIN32) && !defined(Q_OS_SYMBIAN)
#include "../QBtSerialPortServer_stub.h"
#endif

QBT_NAMESPACE_BEGIN

//////////////////////////////////////////////////
// QBtSerialPortServer::QBtSerialPortServer()	//
// Defaul constructor							//
//////////////////////////////////////////////////
QBtSerialPortServer::QBtSerialPortServer(QObject *parent) :
    QObject(parent), _advertiser(0), _isConnected(false)
{
#ifdef Q_OS_SYMBIAN
    QT_TRAP_THROWING(_implPtr = QBtSerialPortServerPrivate::NewL(this));
#else
    _implPtr = new QBtSerialPortServerPrivate(this);
#endif
}

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

void QBtSerialPortServer::startServer (const QBtUuid & serviceId, const QString& serviceName)
{
    QBtService tmpService;
    tmpService.setName (serviceName);
    tmpService.setClass (serviceId);
    setTransmittingService(tmpService);

	#ifdef Q_OS_SYMBIAN
		QT_TRAP_THROWING (_implPtr->StartListenerL());
	#else
		_implPtr->StartListener();
	#endif

}

void QBtSerialPortServer::stopServer()
{
	#ifdef Q_OS_SYMBIAN
		QT_TRAP_THROWING (_implPtr->StopListenerL() );
	#else
		_implPtr->StopListener();
	#endif

}

void QBtSerialPortServer::sendData(const QString & data)
{
    _implPtr->SendData(data);
}

bool QBtSerialPortServer::isConnected()
{
    return _isConnected;
}

const QBtService & QBtSerialPortServer::getTransmittingServiceInfo() const
{
   return _service;
}

void QBtSerialPortServer::setTransmittingService (const QBtService& service)
{
    _service = service;
}

void QBtSerialPortServer::setConnectionStatus(bool connected)
{
    _isConnected = connected;
}

void QBtSerialPortServer::startAdvertisingService(const QBtService& service)
{
    setTransmittingService(service);

    _advertiser = new QBtServiceAdvertiser(this);
    _advertiser->startAdvertising (service);
}

void QBtSerialPortServer::stopAdvertisingService()
{
    if(_advertiser)
    {
        _advertiser->stopAdvertising();
        delete _advertiser;
        _advertiser = NULL;
    }
}

QBT_NAMESPACE_END


code:
/*
 * QBtSerialPortServer_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 "../QBtSerialPortServer_stub.h"

QBtSerialPortServerPrivate::QBtSerialPortServerPrivate(QBtSerialPortServer* publicClass) :
		p_ptr(publicClass)
{
}

QBtSerialPortServerPrivate::~QBtSerialPortServerPrivate()
{

}

void QBtSerialPortServerPrivate::StartListener()
{

}

void QBtSerialPortServerPrivate::StopListener()
{

}

void QBtSerialPortServerPrivate::SendData(const QString data)
{

}

repo_name: snapshot/qbluetooth

license: unknown


code:
/*
 * QBtSerialPortServer_symbian.cpp
 *
 *
 *      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.
 */

 // TODO: use asserts in methods to check that the class is connected

#include "../QBtSerialPortServer_symbian.h"

#include <QBtAuxFunctions.h>

QBtSerialPortServerPrivate* QBtSerialPortServerPrivate::NewL(QBtSerialPortServer* publicClass)
{
	QBtSerialPortServerPrivate* self = QBtSerialPortServerPrivate::NewLC(publicClass);
	CleanupStack::Pop(self);
	return self;
}

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

void QBtSerialPortServerPrivate::ConstructL()
{
	if(iSocketServ.Connect() != KErrNone)
		emit p_ptr->error(QBtSerialPortServer::ErrorUnavailable);
}

// ----------------------------------------------------------------------------
// QBtSerialPortServerPrivate::QBtSerialPortServerPrivate(QBtSerialPortServer* publicClass)
//
// constructor
// ----------------------------------------------------------------------------
QBtSerialPortServerPrivate::QBtSerialPortServerPrivate(QBtSerialPortServer* publicClass):
	CActive(CActive::EPriorityStandard),
	iIsConnected(EFalse),
	queueSize(4),
	iState(ENone),
	restartAtDisconnect(false),
    iMessage (0),
	p_ptr(publicClass)
{
	CActiveScheduler::Add(this);
}

// ----------------------------------------------------------------------------
// QBtSerialPortServerPrivate::~QBtSerialPortServerPrivate()
//
// destructor
// ----------------------------------------------------------------------------
QBtSerialPortServerPrivate::~QBtSerialPortServerPrivate()
{
	// close sockets, must not throw
	TRAPD (error, StopListenerL() );

	// cancel active object
	if(IsActive())
		Cancel();

   if (iMessage)
      delete iMessage;
}

// ----------------------------------------------------------------------------
// QBtSerialPortServerPrivate::StartListener()
//
// start listener.  listener will open a listening socket on a channel (port)
// gotten from GetOpt() call.
// ----------------------------------------------------------------------------
void QBtSerialPortServerPrivate::StartListenerL()
{
	TInt aChannel;

	// get out if we're already running..
	if (iState != ENone)
	{
		QT_TRYCATCH_LEAVING (emit p_ptr->error(QBtSerialPortServer::ErrorAlreadyInUse) );
		return;
	}

	// set this active object to connecting state
	iState=EConnecting;

	// load protocol, RFCOMM
	TProtocolDesc pdesc;
	User::LeaveIfError (iSocketServ.FindProtocol(_L("RFCOMM"), pdesc));

	// open a socket
	User::LeaveIfError (iListenSock.Open (iSocketServ, pdesc.iAddrFamily,pdesc.iSockType,QBtConstants::RFCOMM) );

	// get listening channel
	User::LeaveIfError (iListenSock.GetOpt(KRFCOMMGetAvailableServerChannel, KSolBtRFCOMM, aChannel));

	// bluetooth socket address object
	TBTSockAddr btsockaddr;
	btsockaddr.SetPort(aChannel);

	// bind socket
	User::LeaveIfError (iListenSock.Bind(btsockaddr));
	// listen on port
	iListenSock.Listen (queueSize);

	// advertise service
	QBtService newService;

    newService.setName (p_ptr->_service.getName());
    newService.setClass (p_ptr->_service.getClass() );
    newService.setPort (aChannel);
    newService.addProtocol (QBtUuid (QBtConstants::L2CAP) );
    newService.addProtocol (QBtUuid (QBtConstants::RFCOMM) );

	p_ptr->startAdvertisingService(newService);

	// close old accepted socket if open
	iSock.Close();

	// open blank socket and pass it to accept to be assigned a proper
	// socket upon completion of Accept()
	User::LeaveIfError(iSock.Open(iSocketServ));

	// set to accept incoming connections, active object will handle
	iListenSock.Accept(iSock,iStatus);

	if(!IsActive())
		SetActive();

	QT_TRYCATCH_LEAVING (emit p_ptr->serverStarted() );
}

// ----------------------------------------------------------------------------
// QBtSerialPortServerPrivate::StopListener()
//
// stops the listener by closing the listening socket
// ----------------------------------------------------------------------------
void QBtSerialPortServerPrivate::StopListenerL()
{
	// kill sockets
	if (iState != ENone)
	{
		// cancel all pending socket operations
		iSock.CancelAll();
		iListenSock.CancelAll();

		iSock.Close();
		iListenSock.Close();
		iState=ENone;

		p_ptr->stopAdvertisingService();

		QT_TRYCATCH_LEAVING (emit p_ptr->serverStopped() );
	}
}

// ----------------------------------------------------------------------------
// QBtSerialPortServerPrivate::SendData(const QString data)
//
// send data to remote device, write data to socket.
// ----------------------------------------------------------------------------
/*
void QBtSerialPortServerPrivate::SendData(const QString & data)
{
	if ( iState!=EWaiting )
		return;

	QByteArray tmpArray = data.toUtf8();
	TPtrC8 message8;
	message8.Set((const TUint8 *)tmpArray.constData(), tmpArray.size());

	// cancel any read requests on socket
	if(IsActive())
	{
		iSock.CancelAll();
		iListenSock.CancelAll();
		Cancel();
	}
	// try to send message by writing to socket
	// - set the state of this active object to "sending"
	iState=ESending;

	// - make async socket write request
	iSock.Write(message8, iStatus);

	// - start waiting async req response (iState) from active scheduler
	SetActive();
}
*/

void QBtSerialPortServerPrivate::SendData (const QString& data)
{
    QByteArray array = data.toUtf8();
    SendData (array);
}

// ----------------------------------------------------------------------------
// QBtSerialPortClientPrivate::SendData(const QByteArray& data)
//
// send given data to remote device, write to connected socket
// ----------------------------------------------------------------------------
void QBtSerialPortServerPrivate:: SendData (const QByteArray& data)
{
    TPtrC8 desc8 (reinterpret_cast<const TText8*> (data.constData()), data.size());

    // delete previous data
    if (iMessage)
        delete iMessage;

    iMessage = HBufC8::NewL(desc8.Length());
    iMessage->Des().Copy(desc8);

    // cancel any read requests on socket
    iSock.CancelRead();

    if (IsActive())
        Cancel();

    // send message
    iState = ESending;

    iSock.Write (*iMessage, iStatus);
    SetActive();
}

// ----------------------------------------------------------------------------
// QBtSerialPortServerPrivate::ReceiveData()
//
// receive more data from listening socket, asynchronously.
// ----------------------------------------------------------------------------
void QBtSerialPortServerPrivate::ReceiveData()
{
    // cancel pending operations
    iSock.CancelRead();

    if (IsActive())
      Cancel();

	// set state to waiting - for RunL()
	iState = EWaiting;

	// make async request
	iSock.RecvOneOrMore(iBuffer, 0, iStatus, iLen);

	// set as active to get the async req response (iState) in RunL()
	SetActive();
}

void QBtSerialPortServerPrivate::RunL()
{
    // error ?
    if (iStatus != KErrNone)
	{
		StopListenerL();
		HandleListenerDisconnectedL();

		if(restartAtDisconnect)
			StartListenerL();

		return;
	}

    //
    switch (iState)
	{
		case EConnecting:
		{
            // connected listening socket!
            iIsConnected = ETrue;

            // prepare for receiving data
			ReceiveData();

            // notify
            TBTSockAddr sockAddr;
            iSock.RemoteName (sockAddr);
            TBTDevAddr devAddr (sockAddr.BTAddr().Des());
            QBtAddress clientAddress (devAddr);

            QT_TRYCATCH_LEAVING (emit p_ptr->clientConnected (clientAddress) );

			break;
		}

		case EWaiting:
		{
            // we got incoming data!
            QString receivedString = QString::fromUtf8((char*)iBuffer.Ptr(), iBuffer.Size());

            // start expecting new incoming data
            ReceiveData();

            // notify
            QT_TRYCATCH_LEAVING (emit p_ptr->dataReceived (receivedString) );
            break;
		}

		case ESending:
		{
            // start expecting new incoming data
            ReceiveData();

            // notify
            QT_TRYCATCH_LEAVING  (emit p_ptr->dataSent() );
            break;

		}
		default:
			break;
	}
}

TInt QBtSerialPortServerPrivate::RunError(TInt /*aError*/)
{
	// add the error handling
	return KErrNone;
}

void QBtSerialPortServerPrivate::DoCancel()
{

}

// ----------------------------------------------------------------------------
// QBtSerialPortServerPrivate::IsConnected()
//
// returns true if listener has been connected to
// ----------------------------------------------------------------------------
TBool QBtSerialPortServerPrivate::IsConnected()
{
	return iIsConnected;
}

// ----------------------------------------------------------------------------
// QBtSerialPortServerPrivate::HandleListenerDataReceivedL(TDesC& aData)
//
// emit signal to indicate successfull data receiving
// @param the data received
// ----------------------------------------------------------------------------
void QBtSerialPortServerPrivate::HandleListenerDataReceivedL(const QString & aData)
{
	//QString dataStr = QString::fromUtf8((char*)aData.Ptr(), aData.Length());
	QT_TRYCATCH_LEAVING (emit p_ptr->dataReceived(aData) );
}

// ----------------------------------------------------------------------------
// QBtSerialPortServerPrivate::HandleListenerConnectedL()
//
// emit signal that a client was successfully connected
// ----------------------------------------------------------------------------
void QBtSerialPortServerPrivate::HandleListenerConnectedL()
{
	TBTSockAddr sockAddr;
	iSock.RemoteName(sockAddr);
	TBTDevAddr devAddr(sockAddr.BTAddr().Des());
	QBtAddress clientAddress(devAddr);

	iIsConnected=ETrue;
	QT_TRYCATCH_LEAVING  (emit p_ptr->clientConnected(clientAddress) );
}

// ----------------------------------------------------------------------------
// QBtSerialPortServerPrivate::HandleListenerDisconnectedL()
//
// emit signal that client disconnected
// ----------------------------------------------------------------------------
void QBtSerialPortServerPrivate::HandleListenerDisconnectedL()
{
	iIsConnected=EFalse;
	QT_TRYCATCH_LEAVING (emit p_ptr->clientDisconnected() );
}

// ----------------------------------------------------------------------------
// QBtSerialPortServerPrivate::HandleListenerDataSend()
//
// emit signal that client sent successfully data to the server
// ----------------------------------------------------------------------------
void QBtSerialPortServerPrivate::HandleListenerDataSendL()
{
	QT_TRYCATCH_LEAVING  (emit p_ptr->dataSent() );
}

void QBtSerialPortServerPrivate::SetListeningQueueSize(TInt size)
{
	if(size > 0)
		queueSize = size;
}

/*
void SetSecurity()
{
	//now set security

	//old way to set security is in Listener.cpp
	//QBtSerialPortServerPrivate::SetSecurityL(TInt aChannel)
	TBTServiceSecurity secSettings;

	TUid settingsUID;
	settingsUID.iUid = KBT_serviceID;
	secSettings.SetUid(settingsUID);
	//the old way involved the following two steps:
	//secSettings.SetChannelID(aChannel);
	//secSettings.SetProtocolID(KSolBtRFCOMM);
	secSettings.SetAuthentication(EFalse);
	secSettings.SetAuthorisation(EFalse);
	secSettings.SetEncryption(EFalse);

	// attach the security settings.
	btsockaddr.SetSecurity(secSettings);
}
*/


code:
/*
 * QBtSerialPortServer_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 "../QBtSerialPortServer_win32.h"

QBT_NAMESPACE_BEGIN

QBtSerialPortServerPrivate::QBtSerialPortServerPrivate(QBtSerialPortServer* publicClass) :
		p_ptr(publicClass)
{
}

QBtSerialPortServerPrivate::~QBtSerialPortServerPrivate()
{
	emit p_ptr->error(QBtSerialPortServer::ErrorNotSupported);
}

void QBtSerialPortServerPrivate::StartListener()
{
	emit p_ptr->error(QBtSerialPortServer::ErrorNotSupported);
}

void QBtSerialPortServerPrivate::StopListener()
{
	emit p_ptr->error(QBtSerialPortServer::ErrorNotSupported);
}

void QBtSerialPortServerPrivate::SendData(const QString /*data*/)
{
	emit p_ptr->error(QBtSerialPortServer::ErrorNotSupported);
}

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 QBTSERIALPORTSERVER_H
#define QBTSERIALPORTSERVER_H

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

#include <QBtUuid.h>

QBT_NAMESPACE_BEGIN

//forward declaration
class QBtSerialPortServerPrivate;

/**
 * This class creates a Serial Port Server.
 *
 * After instantiation user can call startServer(const QString&)
 * to start the server and wait for a client to connect. From the
 * serviceName argument user can specify the name of the RFCOMM service
 * which is how the service will be identified by other devices. By default
 * the name is MyRFCOMM.
 *
 * If server is started successfully then serverStarted() signal is emitted.
 *
 * When a remote client is connected to the local running server
 * clientConnected(const QBtAddress &) is emitted and from that point and
 * on the data transmittion can start.
 *
 * To send data to the client use sendData(const QString &). If successfull
 * dataSent() signal is emitted.
 *
 * When data are received successfully from the remote client dataReceived(const QString &)
 * signal is emitted.
 *
 * If client disconnects,  clientDisconnected() will be emitted and user must
 * call startServer(const QString &) to initialize server again to be ready to
 * accept new connection.
 *
 * The connection to a client (if any) is closed when stopServer() is called along
 * with the termination of advertising of the SPP service.
 *
 * In case of an error error(QBtSerialPortServer::ErrorCode) is called.
 */
class DLL_EXPORT QBtSerialPortServer : public QObject
{
    Q_OBJECT

public:

    enum ErrorCode
    {
        ErrorAlreadyInUse,
        ErrorNotSupported,
        ErrorUnavailable,
        ErrorUndefinedError
    };

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

    /**
     * Get the status of the connection.
     * @return true if connected.
     */
    bool isConnected();

    /**
     * If startServer() function is already called then using this function
     * the user can acquire the information of the transmitting service that
     * represents this server to the outside world.
     */
    const QBtService & getTransmittingServiceInfo() const;

protected:
    void setTransmittingService (const QBtService& service);

    /**
     * Set the flag inside this object which represents the connection status.
     * NOTE: This flag is updated automatically whenever the connection status
     * changes.
     */
    void setConnectionStatus(bool connected);

    /**
     * startAdvertisingService()
     *
     * Initializes a new advertiser and starts the transmitting of the
     * service passed as argument.
     */
    void startAdvertisingService(const QBtService& service);

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

public slots:
    /*
     * When server is started, a custom bluetooth service is advertised
     * through QBtServiceAdvertiser. This service can be retrieved using
     * getTransmittingServiceInfo(). If needed, the user can set the name
     * of the transmitting service when calling this function.
     */
    void startServer (const QBtUuid & serviceId, const QString& serviceName = "My RFCOMM service");

    /**
     * stopServer()
     *
     * Stops the server, terminates the service transmittion and disconnects
     * from any device connected
     */
    void stopServer();

    /**
     * sendData()
     *
     * If connected to a remote client, sends the data passed as argument
     * to the client. If successfull, dataSent() signal is emitted.
     *
     * @param data The data to be send.
     */
    void sendData (const QString & data);

signals:
    /**
    * Emitted when server is successfully started and ready to use.
    */
    void serverStarted();

    /**
     * Emitted when service advertising is terminated. If any client is connected the
     * a clientDisconnected() signal will be emitted as well.
     */
    void serverStopped();

    /**
     * Emitted when a remote client is connected to the local running server.
     */
    void clientConnected (const QBtAddress & clientAddress);

    /**
     * Emitted when a remote client is disconnected either by a normal disconnection
     * or by a problem to the connection (ex. loss of signal, power off bluetooth hardware device)
     */
    void clientDisconnected();

    /**
     * Emitted after calling sendData() function if data are send successfully to the remote client.
     */
    void dataSent();

    /**
     * Emitted when data are received successfully from the remote client.
     */
    void dataReceived (const QString & data);

    /**
     * Emitted in case of error.
     */
    void error (QBtSerialPortServer::ErrorCode code);

private:
    // Service Advertiser
    QBtServiceAdvertiser* _advertiser;

    //transmitting service
    QBtService _service;

    //pointer to implementation
    QBtSerialPortServerPrivate *_implPtr;

    // status
    bool _isConnected;

    friend class QBtSerialPortServerPrivate;

};

QBT_NAMESPACE_END

//Q_DECLARE_METATYPE(QBT_PREPEND_NAMESPACE(QBtSerialPortServer))

#endif // QBTSERIALPORTSERVER_H


code:
/*
 * QBtSerialPortServer_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 QBTSERIALPORTSERVER_STUB_H_
#define QBTSERIALPORTSERVER_STUB_H_

#include "QBtSerialPortServer.h"

class QBtSerialPortServerPrivate
{
public:
    QBtSerialPortServerPrivate (QBtSerialPortServer* publicClass);
    ~QBtSerialPortServerPrivate();

    void StartListener();
    void StopListener();
    void SendData(const QString data);

private:
    QBtSerialPortServer* p_ptr;
};

#endif /* QBTSERIALPORTSERVER_STUB_H_ */


code:
/*
 * QBtSerialPortServer_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 QBTSERIALPORTSERVER_SYMBIAN_H_
#define QBTSERIALPORTSERVER_SYMBIAN_H_

#include <e32base.h>

#include <es_sock.h>
#include <btdevice.h>
#include <bt_sock.h>
#include <btmanclient.h> // v2.0 bt_sock.h
#include <e32property.h>

//KErrPermissionDenied alredyexists
#include "QBtSerialPortServer.h"

class QBtSerialPortServerPrivate : public CActive
{
public:

	/*!
	 * NewL()
	 *
	 * Create new QBtSerialPortServerPrivate object
	 * return a pointer to the created instance of QBtSerialPortServerPrivate
	 */
	static QBtSerialPortServerPrivate* NewL(QBtSerialPortServer* publicClass);

	/*!
	 * NewLC()
	 *
	 */
	static QBtSerialPortServerPrivate* NewLC(QBtSerialPortServer* publicClass);

	/*!
	 * ~CConnector()
	 *
	 * Destroy the object and release all memory objects
	 */
	~QBtSerialPortServerPrivate();

	/*!
	 * StartListener()
	 *
	 * Starts the listener.  listener will open a listening socket and
	 * listen on incoming connections.
	 */
	void StartListenerL();

	/*!
	 * StopListener()
	 *
	 * Stops the listener, closes the listening socket.
	 */
	void StopListenerL();

	/*!
	 * SendData()
	 *
	 * Sends data to master.  user will be prompted to enter the
	 * message to send.
	 *
	 * param aData the message to be send.
	 */
	void SendData(const QString & data);

    /*!
     * Sends a byte array.
     */
    void SendData (const QByteArray& data);

	/*!
	 * IsConnected()
	 *
	 * check if listener is connected to.
	 *
	 * return true if listener has a connection from master.
	 */
	TBool IsConnected();

	void SetListeningQueueSize(TInt size);

protected:

	/*!
	 * RunL()
	 *
	 * Handle the active objects request completion.
	 */
	void RunL();

	/*!
	 * DoCancel()
	 *
	 * Cancels the outstanding request on active object.
	 */
	void DoCancel();

	TInt RunError(TInt aError);

private:

	/*!
	 * QBtSerialPortServerPrivate()
	 *
	 * Perform the first phase of two phase construction
	 *
	 * @param The qt public class
	 */
	QBtSerialPortServerPrivate(QBtSerialPortServer* publicClass);

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

	/*!
	 * ReceiveData()
	 *
	 * Receive data from listening socket.
	 */
	void ReceiveData();

	/*!
	 * HandleListenerDataReceivedL()
	 *
	 * Handles the data received from a master.
	 *
	 * param aData the data received.
	 */
	void HandleListenerDataReceivedL(const QString & aData);

	/*!
	 * HandleListenerConnectedL()
	 *
	 * Handles the event of slave connection (slave was connected to
	 * by master)
	 */
	void HandleListenerConnectedL();

	/*!
	 * HandleListenerDisconnectedL()
	 *
	 * Handles the event of slave disconnection, the master connection
	 * to slave was terminated
	 */
	void HandleListenerDisconnectedL();

	/*!
	 * HandleListenerDataSend()
	 *
	 * Handles the event of sending successfully data to the server.
	 */
	void HandleListenerDataSendL();

private: // data

	// listening socket
	RSocket iListenSock;

	// accepted socket
	RSocket iSock;

    // length of received data
	TSockXfrLength iLen;

    // buffer holding received data
	TBuf8<128> iBuffer;

    // socket server handle
	RSocketServ iSocketServ;

    // listener connection status
	TBool iIsConnected;

    // the state of the listener
	TInt queueSize;

    enum TState
	{
		ENone = 1,
		EConnecting,
		EWaiting,
		ESending
	};

	TState iState;

	//if true when client disconnects, restarts listener
	// to accept the next
	TBool restartAtDisconnect;

    HBufC8* iMessage;

	QBtSerialPortServer* p_ptr;
};
#endif /* QBTSERIALPORTSERVER_SYMBIAN_H_ */


code:
/*
 * QBtSerialPortServer_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 QBTSERIALPORTSERVER_STUB_H_
#define QBTSERIALPORTSERVER_STUB_H_

#include "QBtSerialPortServer.h"
#include <QBtAuxFunctions.h>

QBT_NAMESPACE_BEGIN

class QBtSerialPortServerPrivate
{
public:
    QBtSerialPortServerPrivate(QBtSerialPortServer* punlicClsass);
    ~QBtSerialPortServerPrivate();

    void StartListener();
    void StopListener();
    void SendData(const QString data);

private:
    QBtSerialPortServer* p_ptr;
};

QBT_NAMESPACE_END

#endif /* QBTSERIALPORTSERVER_STUB_H_ */


code:
#ifndef _BTDEVICEFINDER_DLG_SYMBIAN_H_
#define _BTDEVICEFINDER_DLG_SYMBIAN_H_

#include <e32base.h>
#include <BTExtNotifiers.h> //TBTDeviceSelectionParamsPckg,TBTDeviceResponseParamsPckg

class MBTDeviceFinderNotify
 {
 public:
		 virtual void BTDeviceSelectedL() = 0;

		 virtual void BTCanceledL() = 0;
 };

// show a dialog and fills it with found devices
class CBTDeviceFinderDlg: public CActive
{

 public:
         static CBTDeviceFinderDlg* NewL (const TInt aPriority, MBTDeviceFinderNotify& aNotify);
         ~CBTDeviceFinderDlg();
 public:
		 void DiscoverDevicesL();
         void SetSelectionParams (const TBTDeviceSelectionParams& aFilter);
		 const TBTDeviceResponseParams& ResponseParams();

 protected:
		 void RunL();
		 void DoCancel();
 private:
         CBTDeviceFinderDlg (const TInt aPriority,MBTDeviceFinderNotify& aNotify);
		 void ConstructL(void);
 private:
	 RNotifier                     iSelectorNotifier;
	 MBTDeviceFinderNotify&        iNotify;
	 TBTDeviceSelectionParamsPckg  iSelectParamsBuf;
	 TBTDeviceResponseParamsPckg   iResponseParamsBuf;
	 TBool                         iConnected;
 };

#endif


code:
#include "../BTDeviceFinderDlg_symbian.h"

CBTDeviceFinderDlg::CBTDeviceFinderDlg(const TInt aPriority, MBTDeviceFinderNotify& aNotify)
:CActive(aPriority),iNotify(aNotify),iConnected(EFalse)
{
}

CBTDeviceFinderDlg::~CBTDeviceFinderDlg()
{
  Cancel();

  if (iConnected)
  {
    iSelectorNotifier.CancelNotifier (KDeviceSelectionNotifierUid);
    iSelectorNotifier.Close();
  }

}

CBTDeviceFinderDlg* CBTDeviceFinderDlg::NewL(const TInt aPriority, MBTDeviceFinderNotify& aNotify)
{
    CBTDeviceFinderDlg* self = new (ELeave) CBTDeviceFinderDlg(aPriority,aNotify);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop();
    return self;
}

void CBTDeviceFinderDlg::ConstructL(void)
{
  CActiveScheduler::Add(this);
}

void CBTDeviceFinderDlg::DoCancel()
{
  iSelectorNotifier.CancelNotifier( KDeviceSelectionNotifierUid );
}

void CBTDeviceFinderDlg::RunL()
{
   // TODO: shut up leaves??

	// check if the user has selected some device
	switch (iStatus.Int() )
	{
		// user canceled
		case KErrCancel:
			iNotify.BTCanceledL();
			break;

		case KErrNone:
			iNotify.BTDeviceSelectedL();
			break;

		// some error
		default:
			User::Leave(iStatus.Int());
	}

	// close notifier soon; if the callbacks leave, the resources were already fred
    //iSelectorNotifier.CancelNotifier (KDeviceSelectionNotifierUid);
    //iSelectorNotifier.Close();

}

void CBTDeviceFinderDlg::DiscoverDevicesL()
{
  if (!iConnected)
  {
	  User::LeaveIfError(iSelectorNotifier.Connect());
      iConnected = ETrue;
  }

  iSelectorNotifier.StartNotifierAndGetResponse(iStatus,
                  KDeviceSelectionNotifierUid,
                  iSelectParamsBuf,
                  iResponseParamsBuf);
  SetActive();
}

void CBTDeviceFinderDlg::SetSelectionParams(const TBTDeviceSelectionParams& aFilter)
{
  iSelectParamsBuf = aFilter;
}

const TBTDeviceResponseParams& CBTDeviceFinderDlg::ResponseParams()
{
  return iResponseParamsBuf();
}


code:
/*
 * QBtDeviceDiscoverer.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 "../QBtDeviceDiscoverer.h"
#include <QBtAuxFunctions.h>

#if defined(Q_OS_SYMBIAN)
#include "../QBtDeviceDiscoverer_symbian.h"
#elif defined(Q_OS_WIN32)
#include "../QBtDeviceDiscoverer_win32.h"
#elif !defined(Q_OS_WIN32) && !defined(Q_OS_SYMBIAN)
#include "../QBtDeviceDiscoverer_stub.h"
#endif

QBT_NAMESPACE_BEGIN

//////////////////////////////////////////////////
// QBtDeviceDiscoverer::QBtDeviceDiscoverer()	//
// Default constructor							//
//////////////////////////////////////////////////
QBtDeviceDiscoverer::QBtDeviceDiscoverer(QObject *parent) : QObject(parent)
{
#ifdef Q_OS_SYMBIAN
    QT_TRAP_THROWING(_implPtr = QBtDeviceDiscovererPrivate::NewL(this));
#else
    _implPtr = new QBtDeviceDiscovererPrivate(this);
#endif
}

//////////////////////////////////////////////////
// QBtDeviceDiscoverer::~QBtDeviceDiscoverer()	//
// Destructor									//
//////////////////////////////////////////////////
QBtDeviceDiscoverer::~QBtDeviceDiscoverer()
{
    SafeDelete(_implPtr);
}

//////////////////////////////////////////////////
// BluetoothDiscovery::startSearch()			//
// Called to start searching for new devices	//
//////////////////////////////////////////////////
void QBtDeviceDiscoverer::startDiscovery()
{
    _implPtr->DiscoverDevices();
}

//////////////////////////////////////////////////
// BluetoothDiscovery::stopSearch()				//
// Called to stop searching for new devices		//
//////////////////////////////////////////////////
void QBtDeviceDiscoverer::stopDiscovery()
{
    _implPtr->StopDiscovery();
}

//////////////////////////////////////////////////
// BluetoothDiscovery::stopSearch()				//
// Called to stop searching for new devices		//
//////////////////////////////////////////////////
const QBtDevice::List& QBtDeviceDiscoverer::getInquiredDevices() const
{
    return _implPtr->GetInquiredDevices();
}

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

void QBtDeviceDiscoverer::emitDummySignalTest()
{
	QBtDevice* device = new QBtDevice();
	device->setName("TestDevice");
	device->setAddress(QBtAddress(QString("00:26:69:4F:F9:5E")));
	device->setType(QBtDevice::Phone);
	emit newDeviceFound(*device);
}

QBT_NAMESPACE_END


code:
/*
 * QBtDeviceDiscoverer_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 "../QBtDeviceDiscoverer_stub.h"
#include "../QBtDeviceDiscoverer.h"

// ================= MEMBER FUNCTIONS =======================
//
// ---------------------------------------------------------
// QBtDeviceDiscovererPrivate::QBtDeviceDiscovererPrivate()
// Constructor
// ---------------------------------------------------------
//
QBtDeviceDiscovererPrivate::QBtDeviceDiscovererPrivate(QBtDeviceDiscoverer *wrapper)
 : d_ptr(wrapper)
{
}

// ---------------------------------------------------------
// QBtDeviceDiscovererPrivate::~QBtDeviceDiscovererPrivate()
// Destructor
// ---------------------------------------------------------
//
QBtDeviceDiscovererPrivate::~QBtDeviceDiscovererPrivate()
{
}

// ---------------------------------------------------------
// QBtDeviceDiscovererPrivate::startSearch()
// Called to start searching for new devices
// ---------------------------------------------------------
//
void QBtDeviceDiscovererPrivate::DiscoverDevices()
{
    emit d_ptr->error(QBtDeviceDiscoverer::BluetoothNotSupported);
}

// ---------------------------------------------------------
// QBtDeviceDiscovererPrivate::startSearch()
// Called to stop searching
// ---------------------------------------------------------
//
void QBtDeviceDiscovererPrivate::StopDiscovery()
{
    emit d_ptr->error(QBtDeviceDiscoverer::BluetoothNotSupported);
}

QBtDevice::List QBtDeviceDiscovererPrivate::GetInquiredDevices()
{
	return QBtDevice::List();
}


code:
/*
 * QBtDeviceDiscoverer_symbian.cpp
 *
 *
 *      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.
 */

#include "../QBtDeviceDiscoverer_symbian.h"
#include "../QBtDeviceDiscoverer.h"
#include <bt_sock.h>
#include <bttypes.h>

_LIT(KBTLinkManagerTxt,"BTLinkManager");

QBtDeviceDiscovererPrivate* QBtDeviceDiscovererPrivate::NewL(QBtDeviceDiscoverer *publicClass)
{
	QBtDeviceDiscovererPrivate* self = QBtDeviceDiscovererPrivate::NewLC(publicClass);
	CleanupStack::Pop(self);
	return self;
}

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

void QBtDeviceDiscovererPrivate::ConstructL()
{
	User::LeaveIfError(iSocketServ.Connect());
	TProtocolName protocolName(KBTLinkManagerTxt);
	User::LeaveIfError(iSocketServ.FindProtocol(protocolName,iProtocolInfo));
}

// ----------------------------------------------------------------------------
// CDeviceDiscoverer::CDeviceDiscoverer(RSocketServ *aSocketServ,
//                                      MDeviceDiscoObserver *aObserver)
//
// constructor
// ----------------------------------------------------------------------------
QBtDeviceDiscovererPrivate::QBtDeviceDiscovererPrivate (QBtDeviceDiscoverer *publicClass)
:	CActive (CActive::EPriorityStandard),
 	sizeOfListeningQueue(4),
 	p_ptr(publicClass),
 	iLIAC (false),
 	iIsBusy (false)
{
	CActiveScheduler::Add(this);
	iDevList = new QBtDevice::List();
}

// ----------------------------------------------------------------------------
// CDeviceDiscoverer::~CDeviceDiscoverer()
//
// destructor
// ----------------------------------------------------------------------------
QBtDeviceDiscovererPrivate::~QBtDeviceDiscovererPrivate()
{
	// cancel active object
	if(IsActive())
		Cancel();

	//iResolver.Close();
	delete iDevList;
}

// ----------------------------------------------------------------------------
// CDeviceDiscoverer::DiscoverDevicesL(TDeviceDataList *aDevDataList)
//
// discover remote devices.  RHostResolver will be used to do the discovery.
// any found devices will be placed in aDevDataList.
// ----------------------------------------------------------------------------
void QBtDeviceDiscovererPrivate::DiscoverDevices()
{
	if (!IsActive())
	{
		// initialize host resolver
		// load protocol for discovery
		iResolver.Close();
		TInt err = iResolver.Open(iSocketServ, iProtocolInfo.iAddrFamily, iProtocolInfo.iProtocol);
		if (err)
		{
			EmitErrorSignal (QBtDeviceDiscoverer::BluetoothInUse);
			return;
		}

		// set as busy
		iIsBusy = true;

		// wipe existing device data list, start fresh
		iDevList->clear();

		// start device discovery by invoking remote address lookup
		TUint myIAC(iLIAC ? KLIAC : KGIAC);
		iAddr.SetIAC(myIAC);

		iAddr.SetAction(KHostResInquiry|KHostResName|KHostResIgnoreCache);
		iResolver.GetByAddress(iAddr, iEntry, iStatus);
		emit p_ptr->discoveryStarted();
		SetActive();
	}
	else
	{
		EmitErrorSignal (QBtDeviceDiscoverer::BluetoothInUse) ;
		return;
	}
}

void QBtDeviceDiscovererPrivate::RunL()
{
	// RHostResolver.GetByAddress(..) has completed, process results
	if ( iStatus == KErrNone )
	{
		TBTSockAddr address = iEntry().iAddr;
		TBTDevAddr btAddress = address.BTAddr();

		//QByteArray btAddressArray((const char*)btAddress.Des().Ptr(), 6);
		QBtAddress qtBtDeviceAddress(btAddress);

		THostName nameDevice = iEntry().iName;
		QString qtNameDevice = QString::fromUtf16(nameDevice.Ptr(),nameDevice.Length());

		TInquirySockAddr& sa = TInquirySockAddr::Cast( iEntry().iAddr );
		//TUint8 minorClass = sa.MinorClassOfDevice();
		//quint8 qMinorClass = quint8(minorClass);

		//Set major device class
		TUint16 majorClass = sa.MajorClassOfDevice();
		QBtDevice::DeviceMajor qtDeviceMajorClass;
		switch (majorClass) {
		case 0x00: //computer
			qtDeviceMajorClass = QBtDevice::Miscellaneous;
			break;
		case 0x01:
			qtDeviceMajorClass = QBtDevice::Computer;
			break;
		case 0x02:
			qtDeviceMajorClass = QBtDevice::Phone;
			break;
		case 0x03:
			qtDeviceMajorClass = QBtDevice::LANAccess;
			break;
		case 0x04:
			qtDeviceMajorClass = QBtDevice::AudioVideo;
			break;
		case 0x05:
			qtDeviceMajorClass = QBtDevice::Peripheral;
			break;
		case 0x06:
			qtDeviceMajorClass = QBtDevice::Imaging;
			break;
        case 0x07:
            qtDeviceMajorClass = QBtDevice::Wearable;
            break;
        case 0x08:
            qtDeviceMajorClass = QBtDevice::Toy;
            break;
		default:
			qtDeviceMajorClass = QBtDevice::Uncategorized;
			break;
		}

		//QBtDevice* remoteDevice = new QBtDevice(qtNameDevice, qtBtDeviceAddress, qtDeviceMajorClass);
		QBtDevice remoteDevice (qtNameDevice, qtBtDeviceAddress, qtDeviceMajorClass);
		QT_TRYCATCH_LEAVING (EmitNewDeviceFoundSignal (remoteDevice));

		// store on list
		iDevList->append (remoteDevice);

		// next
		iResolver.Next(iEntry,iStatus);
		SetActive();
	}
	else if (iStatus == KErrHostResNoMoreResults) {
        // Note emit may throw. We translate to Leave here.
		QT_TRYCATCH_LEAVING (EmitDiscoveryStoppedSignal() );
	}
    else {
    	QT_TRYCATCH_LEAVING (EmitDiscoveryStoppedSignal() );
		//ErrorConvertToLocalL(iStatus.Int());
    }
}

void QBtDeviceDiscovererPrivate::DoCancel()
{
	// Note that must trap any errors here - Cancel is called in destructor and destructor must not throw.
	QT_TRY
	{
		EmitDiscoveryStoppedSignal();
	}
	QT_CATCH (std::exception& e)
	{}

	iResolver.Cancel();
}

// ----------------------------------------------------------------------------
// CDeviceDiscoverer::HasDevices()
//
// returns true if any devices were discovered
// ----------------------------------------------------------------------------
TBool QBtDeviceDiscovererPrivate::HasDevices()
{
	//TBool exists = EFalse;
	return iDevList->size() > 0;
}

// ----------------------------------------------------------------------------
// CBluetoothPMPExampleEngine::SetLIAC
// ----------------------------------------------------------------------------
void QBtDeviceDiscovererPrivate::SetLIAC( TBool aState )
{
	iLIAC = aState;
}

// ----------------------------------------------------------------------------
// CBluetoothPMPExampleEngine::StopDiscovery
// ----------------------------------------------------------------------------
void QBtDeviceDiscovererPrivate::StopDiscovery()
{
	if (IsActive())
		Cancel();
	else
	{
		// Note, may throw. That is OK, stopSearch() is called from Qt code only.
		EmitErrorSignal (QBtDeviceDiscoverer::BluetoothAlreadyStopped) ;
	}
}

// ----------------------------------------------------------------------------
// QBtDeviceDiscovererPrivate::GetInquiredDevices
// Gets the list of devices that where found during the last search
// ----------------------------------------------------------------------------
const QBtDevice::List& QBtDeviceDiscovererPrivate::GetInquiredDevices() const
{
	return *iDevList;
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
TBool QBtDeviceDiscovererPrivate::IsBusy() const
{
	return iIsBusy;
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void QBtDeviceDiscovererPrivate::EmitErrorSignal (QBtDeviceDiscoverer::DeviceDiscoveryErrors error)
{
	try
	{
		emit p_ptr->error (error);
		iIsBusy = false;
	}
	catch (...)
	{
		iIsBusy = false;
		throw;
	}

}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void QBtDeviceDiscovererPrivate::EmitDiscoveryStoppedSignal()
{
	try
	{
		emit p_ptr->discoveryStopped();
		iIsBusy = false;
	}
	catch (...)
	{
		iIsBusy = false;
		throw;
	}

}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void QBtDeviceDiscovererPrivate::EmitNewDeviceFoundSignal (const QBtDevice & device)
{
	try
	{
		emit p_ptr->newDeviceFound (device);
		iIsBusy = false;
	}
	catch (...)
	{
		iIsBusy = false;
		throw;
	}

}


code:
/*
 * QBtDeviceDiscoverer_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 "../QBtDeviceDiscoverer_win32.h"
#include "../QBtDeviceDiscoverer.h"

QBT_NAMESPACE_BEGIN

//////////////////////////
//	Static variables	//
//////////////////////////
QBtDevice::List QBtDeviceDiscovererPrivate::deviceList;
HANDLE QBtDeviceDiscovererPrivate::browseDevEventHandler;
QBtDeviceDiscoverer* QBtDeviceDiscovererPrivate::sp_ptr;
bool QBtDeviceDiscovererPrivate::isSearching = false;

// ================= MEMBER FUNCTIONS =======================
//
// ---------------------------------------------------------
// QBtDeviceDiscovererPrivate::QBtDeviceDiscovererPrivate()
// Constructor
// ---------------------------------------------------------
//
QBtDeviceDiscovererPrivate::QBtDeviceDiscovererPrivate(QBtDeviceDiscoverer *publicClass)
 : p_ptr(publicClass)
{
	Construct();
}

void QBtDeviceDiscovererPrivate::Construct()
{
	if(!QBtAuxFunctions::InitBthSdk())
		return;

	BtSdkCallbackStru cb = {0};

	/* inquiry complete result ind*/
	cb.type = BTSDK_INQUIRY_COMPLETE_IND;
	cb.func = &QBtDeviceDiscovererPrivate::InquiryCompleteResult;
	Btsdk_RegisterCallback4ThirdParty(&cb);

	/* inquiry result ind*/
	cb.type = BTSDK_INQUIRY_RESULT_IND;
	cb.func = &QBtDeviceDiscovererPrivate::ReportInquiryResult;
	Btsdk_RegisterCallback4ThirdParty(&cb);
}

// ---------------------------------------------------------
// QBtDeviceDiscovererPrivate::~QBtDeviceDiscovererPrivate()
// Destructor
// ---------------------------------------------------------
//
QBtDeviceDiscovererPrivate::~QBtDeviceDiscovererPrivate()
{
	StopDiscovery();

	BtSdkCallbackStru cb;
	cb.type = BTSDK_INQUIRY_COMPLETE_IND;
	cb.func = NULL;
	Btsdk_RegisterCallback4ThirdParty(&cb);

	cb.type = BTSDK_INQUIRY_RESULT_IND;
	cb.func = NULL;
	Btsdk_RegisterCallback4ThirdParty(&cb);

	Btsdk_RegisterGetStatusInfoCB4ThirdParty(NULL);

	QBtAuxFunctions::DeinitBthSdk();
}

// ---------------------------------------------------------
// QBtDeviceDiscovererPrivate::startSearch()
// Called to start searching for new devices
// ---------------------------------------------------------
//
void QBtDeviceDiscovererPrivate::DiscoverDevices()
{
	if(isSearching)
	{
		emit p_ptr->error(QBtDeviceDiscoverer::BluetoothInUse);
		return;
	}

	deviceList.clear();

	sp_ptr = p_ptr;

	// the first zero means that all device classes are searched
	// and the second that the discovery can find unlimited number
	// of devices
	if (BTSDK_OK == Btsdk_StartDeviceDiscovery(0, 100, 6))
	{
		isSearching = true;
		emit p_ptr->discoveryStarted();
	}
	else
		emit p_ptr->error(QBtDeviceDiscoverer::UnknownError);
}

// ---------------------------------------------------------
// QBtDeviceDiscovererPrivate::startSearch()
// Called to stop searching
// ---------------------------------------------------------
//
void QBtDeviceDiscovererPrivate::StopDiscovery()
{
	Btsdk_StopDeviceDiscovery();
}

QBtDevice::List& QBtDeviceDiscovererPrivate::GetInquiredDevices()
{
	QBtDevice::List* btList = new QBtDevice::List(deviceList);
	return *btList;
}

void QBtDeviceDiscovererPrivate::ReportInquiryResult(BTDEVHDL dev_hdl)
{
	RegisterFoundDevice(dev_hdl);
}

void QBtDeviceDiscovererPrivate::InquiryCompleteResult(void)
{
	isSearching = false;

	if(sp_ptr)
		emit sp_ptr->discoveryStopped();
}

void QBtDeviceDiscovererPrivate::RegisterFoundDevice(BTDEVHDL dev_hdl)
{
	BTUINT8 szDevName[BTSDK_DEVNAME_LEN] = { 0 };
	BTUINT16 usLen = 0;
	BTUINT32 ulDevClass = 0;
	BTUINT8 szBdAddr[6] = {0};
	QBtDevice devInfo;

	usLen = BTSDK_DEVNAME_LEN;

	BTINT32 result = BTSDK_FALSE;
	if ((result = Btsdk_GetRemoteDeviceName(dev_hdl, szDevName, &usLen)) != BTSDK_OK)
	{
		usLen = BTSDK_DEVNAME_LEN;
		ZeroMemory(szDevName, BTSDK_DEVNAME_LEN);
		if ((result = Btsdk_UpdateRemoteDeviceName(dev_hdl, szDevName, &usLen)) != BTSDK_OK)
		{
			strcpy((char*)szDevName, "Unknown");
		}
	}

	devInfo.setName(QString::fromUtf8((char*)szDevName));

	Btsdk_GetRemoteDeviceAddress(dev_hdl, szBdAddr);

	QByteArray btAddrr((char*)szBdAddr, 6);
	devInfo.setAddress(QBtAddress::getAddressFromReversedArray(btAddrr));

	Btsdk_GetRemoteDeviceClass(dev_hdl, &ulDevClass);

	if(ulDevClass & BTSDK_DEVCLS_COMPUTER)
		devInfo.setType(QBtDevice::Computer);
	else if(ulDevClass & BTSDK_DEVCLS_PHONE)
		devInfo.setType(QBtDevice::Phone);
	else if(ulDevClass & BTSDK_DEVCLS_LAP)
		devInfo.setType(QBtDevice::LANAccess);
	else if(ulDevClass & BTSDK_DEVCLS_AUDIO)
		devInfo.setType(QBtDevice::AudioVideo);
	else if(ulDevClass & BTSDK_DEVCLS_PERIPHERAL)
		devInfo.setType(QBtDevice::Peripheral);
	else if(ulDevClass & BTSDK_DEVCLS_IMAGE)
		devInfo.setType(QBtDevice::Imaging);
	else if(ulDevClass & BTSDK_DEVCLS_IMAGE)
		devInfo.setType(QBtDevice::Imaging);
	else if(ulDevClass & BTSDK_DEVCLS_WEARABLE)
		devInfo.setType(QBtDevice::Wearable);
	else
		devInfo.setType(QBtDevice::Uncategorized);

	deviceList.append(devInfo);

	if(sp_ptr)
		emit sp_ptr->newDeviceFound(devInfo);
}

bool QBtDeviceDiscovererPrivate::IsBusy () const
{
	return isSearching;
}

QBT_NAMESPACE_END


code:
#include "../QBtSingleDeviceSelectorUI.h"

#if defined(Q_OS_SYMBIAN)
#include "../QBtSingleDeviceSelectorUI_symbian.h"
#else
#include "../QBtSingleDeviceSelectorUI_stub.h"
#endif

QBT_NAMESPACE_BEGIN

//____________________________________________________________________________

QBtSingleDeviceSelectorUI::QBtSingleDeviceSelectorUI (QWidget* parent)
   : QObject (parent)
{
#ifdef Q_OS_SYMBIAN
    QT_TRAP_THROWING (_impl = QBtSingleDeviceSelectorUIPrivate::NewL(this));
#else
    _impl = new QBtSingleDeviceSelectorUIPrivate (parent, this);
#endif

}

//____________________________________________________________________________

QBtSingleDeviceSelectorUI::~QBtSingleDeviceSelectorUI()
{
   delete _impl;
}

//____________________________________________________________________________

void QBtSingleDeviceSelectorUI::show()
{
#ifdef Q_OS_SYMBIAN
    QT_TRAP_THROWING(_impl->ShowL() );
#else
    _impl->show();
#endif
}

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.
 */

#include <QBtSingleDeviceSelectorUI_stub.h>
#include <QList>
#include <QBtAuxFunctions.h>
#include <QDesktopWidget>
#include <QApplication>

QBT_NAMESPACE_BEGIN

// ----------------------------------------------------------------------------
// QBtSingleDeviceSelectorUIPrivate::::QBtSingleDeviceSelectorUIPrivate(QWidget* parent) :
//		QFrame(parent), prnt(parent)
//
// constuctor
// ----------------------------------------------------------------------------
QBtSingleDeviceSelectorUIPrivate::QBtSingleDeviceSelectorUIPrivate (QWidget* parent, QBtSingleDeviceSelectorUI* publicClass) :
    QDialog(parent), _parent(parent), _selectedDevice(0), _discoverer(0),
    _devList(0), _menu(0), _select(0), _exit(0), _publicClass (publicClass)
{
    //setup UI
    setObjectName(QString::fromUtf8("btDeviceSelectorUIWidget"));
    setAutoFillBackground(true);
    //setFrameShape(QFrame::WinPanel);
    //setFrameShadow(QFrame::Sunken);
    this->setFocus();

    QDesktopWidget* dw = QApplication::desktop();
    int width = dw->screenGeometry().width();
    int height = dw->screenGeometry().height() /4;

    setGeometry(QRect(0, 148 , width, height));

    _verticalLayout = new QVBoxLayout(this);
    _verticalLayout->setSpacing(6);
    _verticalLayout->setMargin(11);
    _verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));

    _label = new QLabel(this);
    _label->setText("Devices:");
    _verticalLayout->addWidget(_label);

    _devList = new QListWidget(this);

    /*QAction* clear = new QAction(tr("&Exit"), this);
    clear->setSoftKeyRole(QAction::NegativeSoftKey);
    connect(clear, SIGNAL(triggered()), this, SLOT(closeWidget()));

    devList->addAction(clear);
    addAction(clear);*/

    _devList->setFocusPolicy(Qt::WheelFocus);
    _devList->setFrameShape(QFrame::WinPanel);
    _devList->setFrameShadow(QFrame::Sunken);
    _devList->setFocus();
    _verticalLayout->addWidget(_devList);

    _select = new QAction(QString("Select"), this);
    _select->setSoftKeyRole(QAction::PositiveSoftKey);
    connect(_select, SIGNAL(triggered()), this, SLOT(selectPressed()));
    addAction(_select);

    _exit = new QAction(QString("Cancel"), this);
    _exit->setSoftKeyRole(QAction::NegativeSoftKey);
    connect(_exit, SIGNAL(triggered()), this, SLOT(exitPressed()));
    addAction(_exit);

    /*menu = new QMenuBar(this);
    menu->addAction(select);
    menu->addAction(exit);

    menu->setNativeMenuBar(true);
    verticalLayout->setMenuBar(menu);*/

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

    _discoverer = new QBtDeviceDiscoverer(parent);

    connect(_discoverer, SIGNAL(newDeviceFound(const QBtDevice&)),
            this, SLOT(populateDeviceList(const QBtDevice&)));

    connect(_devList, SIGNAL(itemActivated(QListWidgetItem *)),
                    this, SLOT(devSelected(QListWidgetItem *)));
    this->hide();

}

// ----------------------------------------------------------------------------
// QBtSingleDeviceSelectorUIPrivate::~QBtSingleDeviceSelectorUIPrivate()
// destructor
// ----------------------------------------------------------------------------
QBtSingleDeviceSelectorUIPrivate::~QBtSingleDeviceSelectorUIPrivate()
{
    SafeDelete(_discoverer);
    //SafeDelete(selectedDevice);
    SafeDelete(_menu);
    SafeDelete(_select);
    SafeDelete(_exit);
}

// ----------------------------------------------------------------------------
// QBtSingleDeviceSelectorUIPrivate::show()
//
// On show, the device discovery starts an the UI is displayed
// ----------------------------------------------------------------------------
void QBtSingleDeviceSelectorUIPrivate::show()
{
    _devicesFound.clear();

    //menu->show();

    //int y1 = menu->geometry().top() - 150;
    //setGeometry(QRect(0, (y1 >= 0) ? y1 : 0 , 240, 150));
    QDialog::show();
    _devList->setFocus(Qt::PopupFocusReason);

    _discoverer->startDiscovery();
    emit _publicClass->discoveryStarted();
}

void QBtSingleDeviceSelectorUIPrivate::populateDeviceList(const QBtDevice& device)
{
    QBtDevice* newDev = new QBtDevice(device);
    _devicesFound.append(*newDev);
    _devList->addItem(device.getName());
}

void QBtSingleDeviceSelectorUIPrivate::devSelected(QListWidgetItem* devName)
{
    for(int i=0; i<_devicesFound.size(); i++)
    {
        if(_devicesFound[i].getName() == devName->text())
        {
            _selectedDevice = &(_devicesFound[i]);
            break;
        }
    }

    if(_selectedDevice)
        emit _publicClass->discoveryCompleted(*_selectedDevice);
    else
        emit _publicClass->discoveryCompleted(QBtDevice());

    this->hide();
    _parent->setFocusProxy(0);

    _discoverer->stopDiscovery();

    _devicesFound.clear();
    _devList->clear();
}

void QBtSingleDeviceSelectorUIPrivate::selectPressed()
{
    QList<QListWidgetItem*> selectedDevices = _devList->selectedItems();
    if(selectedDevices.size() > 0)
        devSelected(selectedDevices[0]);
}

void QBtSingleDeviceSelectorUIPrivate::exitPressed()
{
    this->hide();
    emit _publicClass->userCanceled();
}

QBT_NAMESPACE_END


code:
#include <btdevice.h> //TBTDeviceClass, TBTDeviceName
#include <bttypes.h> //TBTDevAddr

#include "../QBtSingleDeviceSelectorUI.h"
#include "../QBtSingleDeviceSelectorUI_symbian.h"

#include <QtCore>

QBtSingleDeviceSelectorUIPrivate::QBtSingleDeviceSelectorUIPrivate (QBtSingleDeviceSelectorUI* publicClass)
 : _finder (0), _publicClass (publicClass)
{}

QBtSingleDeviceSelectorUIPrivate::~QBtSingleDeviceSelectorUIPrivate()
{
   Cancel();
   delete _finder;
}

QBtSingleDeviceSelectorUIPrivate* QBtSingleDeviceSelectorUIPrivate::NewL (QBtSingleDeviceSelectorUI* publicClass)
{
    QBtSingleDeviceSelectorUIPrivate* self = new (ELeave) QBtSingleDeviceSelectorUIPrivate (publicClass);

	CleanupStack::PushL(self);
		self->ConstructL();
	CleanupStack::Pop();

	return self;
}

void QBtSingleDeviceSelectorUIPrivate::ConstructL()
{
    //CActive::TPriority priority (CActive::EPriorityUserInput);
    //_finder = CBTDeviceFinderDlg::NewL(priority, *this);
}

void QBtSingleDeviceSelectorUIPrivate::Cancel()
{
   if (_finder)
   {
      if (_finder->IsActive() )
         _finder->Cancel();
   }

}

void QBtSingleDeviceSelectorUIPrivate::ShowL()
{
    // cancel and delete previous instance
    Cancel();
    delete _finder;

    // new man
    CActive::TPriority priority (CActive::EPriorityUserInput);
    _finder = CBTDeviceFinderDlg::NewL(priority, *this);

    // here we go
    QT_TRYCATCH_LEAVING (emit _publicClass->discoveryStarted() );
    SelectDeviceL ();
}

void QBtSingleDeviceSelectorUIPrivate::SelectDeviceL ()
{

  /* search only within a specific subset of devices
  TBTDeviceSelectionParams selectionFilter;
  TBTDeviceClass deviceFilter(EMajorServiceObjectTransfer, EMajorDevicePhone,
        EMinorDevicePhoneUnclassified |
         EMinorDevicePhoneCellular |
        EMinorDevicePhoneCordless |
         EMinorDevicePhoneSmartPhone |
         EMinorDevicePhoneWiredModem |
        EMinorDevicePhoneCommonISDNAccess );

  selectionFilter.SetDeviceClass(deviceFilter);
  iFinder->SetSelectionParams(selectionFilter);
  */

    _finder->DiscoverDevicesL();

}

void QBtSingleDeviceSelectorUIPrivate::BTDeviceSelectedL()
{
	//Do something when BT device is selected
	//e.g. get details of the device the user selected

	TBTDeviceResponseParams response = _finder->ResponseParams();
	TBTDevAddr deviceAddress = response.BDAddr();
	TBTDeviceName deviceName = response.DeviceName();
	TBTDeviceClass deviceClass = response.DeviceClass();

	// on to qt types
	QBtAddress address (deviceAddress);

	// name
	QString name = QString::fromUtf16 (deviceName.Ptr(), deviceName.Length());

	// major device class
	QBtDevice::DeviceMajor majorClass;

	switch (deviceClass.MajorDeviceClass() )
	{
		case 0x00: //computer
			majorClass = QBtDevice::Miscellaneous;
			break;
		case 0x01:
			majorClass = QBtDevice::Computer;
			break;
		case 0x02:
			majorClass = QBtDevice::Phone;
			break;
		case 0x03:
			majorClass = QBtDevice::LANAccess;
			break;
		case 0x04:
			majorClass = QBtDevice::AudioVideo;
			break;
		case 0x05:
			majorClass = QBtDevice::Peripheral;
			break;
		case 0x06:
			majorClass = QBtDevice::Imaging;
			break;
		default:
			majorClass = QBtDevice::Uncategorized;
			break;
	}

	// create device
	QBtDevice remoteDevice (name, address, majorClass);

	// if this throws, generate a leave as this is symbian code
	QT_TRYCATCH_LEAVING (emit _publicClass->discoveryCompleted (remoteDevice) );

}

void QBtSingleDeviceSelectorUIPrivate::BTCanceledL()
{
	// if this throws, generate a leave as this is symbian code
	QT_TRYCATCH_LEAVING  (emit _publicClass->userCanceled() );
}


code:
/*
 * QBtDeviceDiscoverer.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 QBTDEVICEDISCOVERER_H_
#define QBTDEVICEDISCOVERER_H_

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

QBT_NAMESPACE_BEGIN

//Forward declaration
class QBtDeviceDiscovererPrivate;

/**
 * Class that contains the mechanism of the device discovery.
 * After instantiation, user can call startDiscovery() to begin the discovery.
 * If calling startDiscovery() is successfull then discoveryStarted() signal is emitted.
 * Any found device is reported through newDeviceFound(QBtDevice) signal or can be retrieved
 * calling GetInquiredDevices() which returns a list of all the found devices till now.
 * When discovery stops, discoveryStopped() signal is emitted.
 *
 * Incase of any errors, the are reported through
 * error(QBtDeviceDiscoverer::DeviceDiscoveryErrors) signal.
 */
class DLL_EXPORT QBtDeviceDiscoverer : public QObject
{
Q_OBJECT

public: //enums
    enum DeviceDiscoveryErrors
        { BluetoothNotSupported, BluetoothInUse, BluetoothAlreadyStopped, BluetoothNotReady,
        DiscoveryCancelled, UnknownError };

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

    /**
     * GetInquiredDevices()
     *
     * returns a reference to the list of devices found (if any)
     */
    Q_INVOKABLE const QBtDevice::List& getInquiredDevices() const;

    /**
     * Returns true if the class if performing a device discovery.
     */
    bool isBusy () const;

	Q_INVOKABLE void emitDummySignalTest();

public slots:
    /**
     * startDiscovery()
     *
     * Start a device discovery.
     * The start and completion of device discovery are reported through
     * discoveryStarted() and discoveryStopped() signals respectively.
     */
    void startDiscovery();

    /**
     * stopDiscovery()
     *
     * Stops device discovery.
     * Signal discoveryStopped() is emitted.
     */
    void stopDiscovery();

signals:
    /**
     * Signaled for every device detected
     * @param remoteDevice The remote device
     */
	void newDeviceFound (QBtDevice remoteDevice);

	//changed to the above because @ emit the classes already written, pass as argument
	// a local variable QBtDevice so i am not sure if the reference will continue to make senses
	// (may be the variable will be destroyed). Alternative we could return a *(new QBtDevice())
	//  but that would lead to memory leak.
	//void newDeviceFound (const QBtDevice & remoteDevice);

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

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

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

private:

    QBtDeviceDiscovererPrivate *_implPtr;
    friend class QBtDeviceDiscovererPrivate;

};

QBT_NAMESPACE_END

//Q_DECLARE_METATYPE(QBT_PREPEND_NAMESPACE(QBtDeviceDiscoverer))

#endif /* QBTDEVICEDISCOVERER_H_ */


code:
/*
 * QBtDeviceDiscoverer_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 QBTDEVICEDISCOVERER_STUB_H_
#define QBTDEVICEDISCOVERER_STUB_H_

#include <QBtDevice.h>
#include <QBtDeviceDiscoverer.h>

class QBtDeviceDiscovererPrivate
{
public:
    QBtDeviceDiscovererPrivate(QBtDeviceDiscoverer *wrapper = 0);
    ~QBtDeviceDiscovererPrivate();

public:
    void DiscoverDevices();
    void StopDiscovery();
    const QBtDevice::List& GetInquiredDevices() const;
    bool IsBusy() const;

private: // Daa
    QBtDeviceDiscoverer *d_ptr;  //Pointer to public interface
};

#endif /* QBTDEVICEDISCOVERER_STUB_H_ */


code:
/*
 * QBtDeviceDiscoverer_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 QBTDEVICEDISCOVERER_SYMBIAN_H_
#define QBTDEVICEDISCOVERER_SYMBIAN_H_

#include <e32base.h>
#include <ES_SOCK.H>
#include <bt_sock.h>

#include <QBtDevice.h>
#include <QBtDeviceDiscoverer.h>

class QBtDeviceDiscovererPrivate : public CActive
{
public:

/*!
 * NewL()
 * Create new CDeviceDiscoverer object
 * return a pointer to the created instance of CDeviceDiscoverer
 */
    static QBtDeviceDiscovererPrivate* NewL(QBtDeviceDiscoverer *publicClass);

/*!
 * NewLC()
 */
    static QBtDeviceDiscovererPrivate* NewLC(QBtDeviceDiscoverer *publicClass);

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

/*!
 * DiscoverDevicesL()
 * Discovers remote bluetooth devices within range.
 * param aDevDataList device data list where the found devices will be placed.
 */
    void DiscoverDevices();

/*!
 * StopDiscovery()
 * Stops ongoing device discovery
 *
 */
    void StopDiscovery();

/*!
 * HasDevices()
 * any devices discovered?
 * return true if any devices were discovered.
 */
    TBool HasDevices();

/*!
 * SetLIAC()
 * Set LimitedDiscoverableStatus status
 *
 */
    void SetLIAC( TBool aState );

    /*
     * Gets the list of devices that where found during the last search
     */
    const QBtDevice::List& GetInquiredDevices() const;

    /**
     * Returns true if the class is busy discovering devices.
     */
    TBool IsBusy() const;

protected:

/*!
 * RunL()
 * Handle the active objects request completion.
 */
    void RunL();

/*!
 * DoCancel()
 * Cancels the outstanding request on active object.
 */
    void DoCancel();

private:

/*!
 * CDeviceDiscoverer()
 * Perform the first phase of two phase construction
 * param aSocketServ reference to socket server
 */
    QBtDeviceDiscovererPrivate(QBtDeviceDiscoverer *publicClass);

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

private:

    void EmitErrorSignal (QBtDeviceDiscoverer::DeviceDiscoveryErrors error);
    void EmitDiscoveryStoppedSignal();
    void EmitNewDeviceFoundSignal (const QBtDevice & device);

private: //data

    // socket server handle
    RSocketServ iSocketServ;
    // device data list, to be filled by resolver results
    QBtDevice::List *iDevList;
    // host resolver
    RHostResolver iResolver;
    TInquirySockAddr iAddr;
    TProtocolDesc iProtocolInfo;
    TNameEntry iEntry;
    TInt sizeOfListeningQueue;

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

    TBool iLIAC;
    TBool iIsBusy;

};

#endif /* QBTDEVICEDISCOVERER_SYMBIAN_H_ */


code:
/*
 * QBtDeviceDiscoverer_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 QBTDEVICEDISCOVERER_STUB_H_
#define QBTDEVICEDISCOVERER_STUB_H_

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

QBT_NAMESPACE_BEGIN

class QBtDeviceDiscovererPrivate
{
public:
    QBtDeviceDiscovererPrivate(QBtDeviceDiscoverer *publicClass = 0);
    ~QBtDeviceDiscovererPrivate();

public:
    void DiscoverDevices();
    void StopDiscovery();
    QBtDevice::List& GetInquiredDevices();
	bool IsBusy () const;

protected:
    void Construct();

private:
    static void ReportInquiryResult(BTDEVHDL dev_hdl);
    static void InquiryCompleteResult(void);
    static void RegisterFoundDevice(BTDEVHDL dev_hdl);
	static void UnregisterBtCallbacks();

private:
	//these are static because of the callbacks...
    static QBtDevice::List deviceList;
    // handle of the win event used to indicate that discovery finished
    static HANDLE browseDevEventHandler;
    static QBtDeviceDiscoverer* sp_ptr;
    static bool isSearching;

    QBtDeviceDiscoverer *p_ptr;  //Pointer to public interface
};

QBT_NAMESPACE_END

#endif /* QBTDEVICEDISCOVERER_STUB_H_ */


code:
/*
 * QBtSingleDeviceSelectorUI.h
 *
 *
 *      Author: ftylitak
 *
 * 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 QBTSINGLEDEVICESELECTORUI_H_
#define QBTSINGLEDEVICESELECTORUI_H_

#include <QtCore/QObject>
#include <QtGui/QWidget>
#include <QBtGlobal.h>
#include <QBtDevice.h>

QBT_NAMESPACE_BEGIN

class QBtSingleDeviceSelectorUIPrivate;

/**
 * This class provides UI for searching remote bluetooth
 * devices, displaying them and selecting one device.
 *
 * When a device is selected, the UI is closed and the
 * device instance is returned through discoveryCompleted()
 * signal.
 * (NOTE: when closed it is not destroyed, just hiden)
 *
 * To use, create an instance of the class and call
 * show(). When shown, discovery starts as well.
 *
 * To get the selected remote device, the discoveryCompleted()
 * signal must be handled.
 */
class DLL_EXPORT QBtSingleDeviceSelectorUI : public QObject
{
    Q_OBJECT

public:
    /**
     * If parent == 0, the list will be showed as an independent
     * widget on the screen, thus it's not necessary for the client application
     * to have a GUI interface.
     *
     * For Symbian, it uses the native bluetooth search dialog. In this case, the "parent"
     * parameter has no effect.
     */
    QBtSingleDeviceSelectorUI (QWidget* parent = 0);

    /**
     * Destructor.
     */
    ~QBtSingleDeviceSelectorUI();

public slots:

    /**
     * On show, the device discovery starts.
     */
    void show();

signals:
    /**
     * Emitted after device discovery stops and user selects the desired device.
     */
    void discoveryCompleted (const QBtDevice & selectedDevice);

    /**
     * Emitted after calling show() if and only if the device discovery starts successfully
     */
    void discoveryStarted();

    /**
     * Emitted when the user closes the UI without choosing any device.
     */
    void userCanceled ();

private:
    QBtSingleDeviceSelectorUIPrivate* _impl;
    friend class QBtSingleDeviceSelectorUIPrivate;

};

QBT_NAMESPACE_END

#endif /* QBTSINGLEDEVICESELECTORUI_H_ */


code:
/*
 * QBtSingleDeviceSelectorUIPrivate.h
 *
 *
 *      Author: ftylitak
 *
 * 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 QBTSINGLEDEVICESELECTORUI_PRIVATE_STUB_H_
#define QBTSINGLEDEVICESELECTORUI_PRIVATE_STUB_H_

#include "DeviceDiscoverer/QBtSingleDeviceSelectorUI.h"
#include <QBtGlobal.h>
#include <QBtTypes.h>
#include <QBtDeviceDiscoverer.h>
#include <QtGui/QListWidget>
#include <QtGui/QLabel>
#include <QtGui/QVBoxLayout>
#include <QtGui/QMenuBar>
#include <QtGui/QAction>
#include <QtCore/QModelIndex>
#include <QtGui/QDialog>

QBT_NAMESPACE_BEGIN

/**
 * This class provides UI for searching remote bluetooth
 * devices, displaying them and selecting one device.
 *
 * When a device is selected, the UI is closed and the
 * device instance is returned through discoveryCompleted()
 * signal.
 * (NOTE: when closed it is not destroyed, just hiden)
 *
 * To use, create an instance of the class and call
 * show(). When shown, discovery starts as well.
 *
 * To get the selected remote device, the discoveryCompleted()
 * signal must be handled.
 */
class QBtSingleDeviceSelectorUIPrivate : public QDialog
{
   Q_OBJECT

public:
    /**
     * if parent == NULL, the list will be showed as indepentant
     * widget on the screen, thus it's not necessary for the client application
     * to have a GUI interface.
     */
    QBtSingleDeviceSelectorUIPrivate(QWidget* parent, QBtSingleDeviceSelectorUI* publicClass);

    /**
     * Destructor.
     */
    ~QBtSingleDeviceSelectorUIPrivate();

public slots:

    /**
     * On show, the device discovery starts.
     */
    void show();

protected slots:

    void populateDeviceList(const QBtDevice& device);
    void devSelected(QListWidgetItem* devName);
    void selectPressed();
    void exitPressed();

private:
    QWidget * _parent;
    QBtDevice* _selectedDevice;
    QBtDeviceDiscoverer* _discoverer;
    QListWidget* _devList;
    QLabel* _label;
    QVBoxLayout *_verticalLayout;
    QList<QBtDevice> _devicesFound;

    QMenuBar* _menu;
    QAction* _select;
    QAction* _exit;

    QBtSingleDeviceSelectorUI* _publicClass;
};

QBT_NAMESPACE_END

#endif


code:
#ifndef QBTDEVICEFINDER_PRIVATE_SYMBIAN_H_
#define QBTDEVICEFINDER_PRIVATE_SYMBIAN_H_

#include <QBtDevice.h>
#include "../BtDeviceFinderDlg_symbian.h"

class CBTDeviceFinderDlg;
class QBtSingleDeviceSelectorUI;

//____________________________________________________________________________

class QBtSingleDeviceSelectorUIPrivate : public CBase, MBTDeviceFinderNotify
{
	public:

        static QBtSingleDeviceSelectorUIPrivate* NewL (QBtSingleDeviceSelectorUI* publicClass);

	public:

        ~QBtSingleDeviceSelectorUIPrivate();

	// mirror public API

	public:

        void ShowL();

	public:

		//from MBTDeviceFinderNotify
		void BTDeviceSelectedL();
		void BTCanceledL();

	private:

        QBtSingleDeviceSelectorUIPrivate (QBtSingleDeviceSelectorUI* publicClass);
		void ConstructL ();

		void SelectDeviceL ();

        void Cancel();

	private:

		//...
        CBTDeviceFinderDlg*         _finder;
        QBtSingleDeviceSelectorUI*  _publicClass;

};

#endif


code:
Copyright � 2006 Nokia Corporation. All rights reserved.
Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation.
Java and all Java-based marks are trademarks or registered trademarks of
Sun Microsystems, Inc. Other product and company names mentioned herein may be
trademarks or trade names of their respective owners.

Subject to the conditions below, you may, without charge:

�  Use, copy, modify and/or merge copies of this software and
   associated documentation files (the �Software�)

�  Publish, distribute, sub-license and/or sell new software
   derived from or incorporating the Software.

This file, unmodified, shall be included with all copies or substantial portions
of the Software that are distributed in source code form.

The Software cannot constitute the primary value of any new software derived
from or incorporating the Software.

Any person dealing with the Software shall not misrepresent the source of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


code:
Copyright � 2006-2009 Nokia Corporation. All rights reserved.
Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation.
Java and all Java-based marks are trademarks or registered trademarks of
Sun Microsystems, Inc. Other product and company names mentioned herein may be
trademarks or trade names of their respective owners.

Subject to the conditions below, you may, without charge:

�  Use, copy, modify and/or merge copies of this software and
   associated documentation files (the �Software�)

�  Publish, distribute, sub-license and/or sell new software
   derived from or incorporating the Software.

This file, unmodified, shall be included with all copies or substantial portions
of the Software that are distributed in source code form.

The Software cannot constitute the primary value of any new software derived
from or incorporating the Software.

Any person dealing with the Software shall not misrepresent the source of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


code:
/*
 * QBtLocalDevice.cpp
 *
 *
 *      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.
 */

#include <QBtLocalDevice.h>
#include <QBtAuxFunctions.h>

#if defined(Q_OS_SYMBIAN)
#include "../QBtLocalDevice_symbian.h"
#elif defined(Q_OS_WIN32)
#include "../QBtLocalDevice_win32.h"
#elif !defined(Q_OS_WIN32) && !defined(Q_OS_SYMBIAN)
#include "../QBtLocalDevice_stub.h"
#endif

QBT_NAMESPACE_BEGIN

QBtAddress QBtLocalDevice::getLocalDeviceAddress()
{
    return QBtLocalDevicePrivate::GetLocalDeviceAddress();
}

bool QBtLocalDevice::isVisible()
{
    return QBtLocalDevicePrivate::IsVisible();
}

void QBtLocalDevice::setVisible (bool value)
{
    QBtLocalDevicePrivate::SetVisible (value);
}

QBtDevice::DeviceMajor QBtLocalDevice::getDeviceClass()
{
    return QBtLocalDevicePrivate::GetDeviceClass();
}

void QBtLocalDevice::setDeviceClass(QBtDevice::DeviceMajor classId)
{
    QBtLocalDevicePrivate::SetDeviceClass(classId);
}

void QBtLocalDevice::setLocalDeviceName (const QString & deviceName)
{
    QBtLocalDevicePrivate::SetLocalDeviceName (deviceName);
}

QString QBtLocalDevice::getLocalDeviceName()
{
    return QBtLocalDevicePrivate::GetLocalDeviceName();
}

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

bool QBtLocalDevice::isBluetoothSupported()
{
    return QBtLocalDevicePrivate::IsBluetoothSupported();
}

void QBtLocalDevice::askUserTurnOnBtPower()
{
    QBtLocalDevicePrivate::AskUserTurnOnBtPower();
}

bool QBtLocalDevice::getBluetoothPowerState()
{
    return QBtLocalDevicePrivate::GetBluetoothPowerState();
}

bool QBtLocalDevice::setBluetoothPowerState (bool value)
{
	return QBtLocalDevicePrivate::SetBluetoothPowerState (value);
}

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

bool QBtLocalDevice::addNewDevice(const QBtDevice& device)
{
    return QBtLocalDevicePrivate::AddNewDevice(device);
}

bool QBtLocalDevice::deleteDevice(const QBtDevice& device)
{
    return QBtLocalDevice::deleteDevice(device.getAddress());
}

bool QBtLocalDevice::deleteDevice(const QBtAddress& address)
{
    return QBtLocalDevicePrivate::DeleteDevice(address);
}

bool QBtLocalDevice::unpairDevice(const QBtDevice& device)
{
    return QBtLocalDevice::unpairDevice(device.getAddress());
}

bool QBtLocalDevice::unpairDevice(const QBtAddress& address)
{
    return QBtLocalDevicePrivate::UnpairDevice(address);
}

QBT_NAMESPACE_END


code:
/*
 * QBtLocalDevice_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 "../QBtLocalDevice_stub.h"

TBool QBtLocalDevicePrivate::isBluetoothSupported()
{
	return false;
}

void QBtLocalDevicePrivate::AskUserTurnOnBtPower()
{
	return;
}

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

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

QBtAddress QBtLocalDevicePrivate::GetLocalDeviceAddress()
{
	return QBtAddress();
}

bool QBtLocalDevicePrivate::GetLimitedDiscoverableStatus()
{
	return false;
}

void QBtLocalDevicePrivate::SetLimitedDiscoverableStatus(bool isDiscoverabilityLimited)
{

}

QBtDevice::DeviceMajor QBtLocalDevicePrivate::GetDeviceClass()
{
	return QBtDevice::Uncategorized;
}

void QBtLocalDevicePrivate::SetDeviceClass(QBtDevice::DeviceMajor classId)
{

}

void QBtLocalDevicePrivate::SetLocalDeviceName(const QString & deviceName)
{

}

QString QBtLocalDevicePrivate::GetLocalDeviceName()
{
	return "";
}

bool QBtLocalDevicePrivate::AddNewDevice(const QBtDevice& device)
{
	return false;
}

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

bool QBtLocalDevicePrivate::DeleteDevice(const QBtAddress& address)
{
	return false;
}

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


code:
/*
 * QBtLocalDevice_symbian.cpp
 *
 *
 *      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.
 */

#include "../QBtLocalDevice_symbian.h"
#include <QBtAuxFunctions.h>
#include <QtGlobal>

// bluetooth engine api plugin
#ifdef __SERIES60_31__
#include <bteng.h>
#else
#include <btengsettings.h>
#endif

///////////////////////////////////////
///	 Bluetooth local properties		///
///////////////////////////////////////

TBool QBtLocalDevicePrivate::DefineProperty(TUint propertyId, RProperty::TType typeEnum)
{
    TInt attErr = RProperty::Define(KPropertyUidBluetoothControlCategory,propertyId,typeEnum);
    if (attErr != KErrNone && attErr != KErrAlreadyExists)
        return EFalse;

    return ETrue;
}

QBtAddress QBtLocalDevicePrivate::GetLocalDeviceAddress()
{
    TUint8 buffer[512];
    TPtr8 value(buffer, 512);
    RProperty::Get( KPropertyUidBluetoothControlCategory,
                    KPropertyKeyBluetoothGetLocalDeviceAddress, value );

    QByteArray bArray((const char*)buffer, 6);
    return QBtAddress(bArray);
}

TBool QBtLocalDevicePrivate::IsVisible()
{
    /*
    TInt value;
    RProperty::Get( KPropertyUidBluetoothControlCategory,
            KPropertyKeyBluetoothGetLimitedDiscoverableStatus, value );

    return value;
    */

    TBool value = EFalse;

    QT_TRAP_THROWING(
    {
#ifdef __SERIES60_31__
        TBTDiscoverabilityMode mode;
        CBTMCMSettings* b = CBTMCMSettings::NewLC ();
        User::LeaveIfError (b->GetDiscoverabilityMode (mode) );

        if (EBTDiscModeHidden == mode)
            value = EFalse;
        else
            value = ETrue;

#else
        TBTVisibilityMode mode;
        CBTEngSettings* b = CBTEngSettings::NewLC();
        User::LeaveIfError(b->GetVisibilityMode (mode) );

        if (EBTVisibilityModeHidden  == mode)
            value = EFalse;
        else
            value = ETrue;

#endif

        CleanupStack::PopAndDestroy();
    });

    return value;
}

void QBtLocalDevicePrivate::SetVisible (TBool value)
{
    /*
    DefineProperty(KPropertyKeyBluetoothGetLimitedDiscoverableStatus, RProperty::EInt);

    RProperty::Set( KPropertyUidBluetoothControlCategory,
            KPropertyKeyBluetoothSetLimitedDiscoverableStatus, limited);
            */

    QT_TRAP_THROWING(
    {
        #ifdef __SERIES60_31__
            TBTDiscoverabilityMode mode;

    if (value)
        mode = EBTDiscModeGeneral;
    else
        mode = EBTDiscModeHidden;

    CBTMCMSettings* b = CBTMCMSettings::NewLC ();
    User::LeaveIfError (b->SetDiscoverabilityModeL (mode) );

#else
            TBTVisibilityMode mode;

    if (value)
        mode = EBTVisibilityModeGeneral;
    else
        mode = EBTVisibilityModeHidden;

    CBTEngSettings* b = CBTEngSettings::NewLC();
    User::LeaveIfError(b->SetVisibilityMode (mode) );

#endif

    CleanupStack::PopAndDestroy();
    });
}

QBtDevice::DeviceMajor QBtLocalDevicePrivate::GetDeviceClass()
{
    TInt value;
    RProperty::Get( KPropertyUidBluetoothControlCategory,
                    KPropertyKeyBluetoothGetDeviceClass, value );

    return (QBtDevice::DeviceMajor)value;
}

void QBtLocalDevicePrivate::SetDeviceClass(QBtDevice::DeviceMajor classId)
{
    DefineProperty(KPropertyKeyBluetoothGetDeviceClass, RProperty::EInt);

    RProperty::Set( KPropertyUidBluetoothControlCategory,
                    KPropertyKeyBluetoothGetDeviceClass, (TInt)classId );
}

QString QBtLocalDevicePrivate::GetLocalDeviceName()
{
    TUint16 buffer[512] = {0};
    TPtr16 value(buffer, 512);
    RProperty::Get( KPropertyUidBluetoothControlCategory,
                    KPropertyKeyBluetoothGetDeviceName, value );

    return QString::fromUtf16((unsigned short*)value.Ptr());
}

void QBtLocalDevicePrivate::SetLocalDeviceName (const QString & deviceName)
{
    DefineProperty(KPropertyKeyBluetoothSetDeviceName, RProperty::EText);

    TPtr16 value ((TUint16*)deviceName.utf16(), deviceName.size());
    RProperty::Set (KPropertyUidBluetoothControlCategory, KPropertyKeyBluetoothSetDeviceName, value );
}

///////////////////////////////
///	 Bluetooth Hardware		///
///////////////////////////////

TBool QBtLocalDevicePrivate::IsBluetoothSupported()
{
    return CFeatureDiscovery::IsFeatureSupportedL(KFeatureIdBt);
}

void QBtLocalDevicePrivate::AskUserTurnOnBtPower()
{
    const TUid KPowerModeSettingNotifierUid = {0x100059E2};

    RNotifier notifier;
    User::LeaveIfError( notifier.Connect() );
    TPckgBuf<TBool> dummy(ETrue);
    TPckgBuf<TBool> reply(EFalse);
    TRequestStatus stat;
    notifier.StartNotifierAndGetResponse(stat, KPowerModeSettingNotifierUid, dummy, reply);

    User::WaitForRequest(stat);
    notifier.CancelNotifier(KPowerModeSettingNotifierUid);
    notifier.Close();
}

TBool QBtLocalDevicePrivate::GetBluetoothPowerState()
{
    TInt value=0;

    QT_TRAP_THROWING(
    {
            CRepository* crep = CRepository::NewLC(KCRUidBluetoothPowerState);
    User::LeaveIfError( crep->Get(KBTPowerState, value) );
    CleanupStack::PopAndDestroy();
}
);

return value;
}

TBool QBtLocalDevicePrivate::SetBluetoothPowerState (TBool value)
{
    QT_TRAP_THROWING(
    {
        #ifdef __SERIES60_31__
            CBTMCMSettings* b = CBTMCMSettings::NewLC ();
    User::LeaveIfError(b->SetPowerState (value) );

#else
            TBTPowerStateValue v = value? EBTPowerOn: EBTPowerOff;
    CBTEngSettings* b = CBTEngSettings::NewLC();
    User::LeaveIfError(b->SetPowerState (v) );
#endif

    CleanupStack::PopAndDestroy();
}
);

return true;

}

///////////////////////////////
///	 Bluetooth Registry		///
///////////////////////////////

TBool QBtLocalDevicePrivate::AddNewDevice(const QBtDevice& device)
{
    try
    {
        CBTDevice* newDev;
        RBTRegServ regServ;
        RBTRegistry view;
        TRequestStatus stat;
        QT_TRAP_THROWING
        (
        newDev = CBTDevice::NewL(device.getAddress().convertToSymbianBtDevAddr()));
        newDev->SetDeviceClass(TBTDeviceClass(device.getType()));
        TBuf8<4> psd(_L8("0000"));
        TPINCodeV10 pinCode10;
        pinCode10.iLength = 4;
        memcpy(pinCode10.iPIN,psd.Ptr(),4);
        TBTPinCode pinCode(pinCode10);
        TPtrC8 name8((const TUint8 *)device.getName().toUtf8().data(),device.getName().toUtf8().size());
        TPtrC16 name16(device.getName().utf16());
        QT_TRAP_THROWING(
        {
                newDev->SetDeviceNameL(name8);
        newDev->SetFriendlyNameL(name16);
        newDev->SetPaired(ETrue);
        newDev->SetPassKey(pinCode);
        regServ.Connect();
        view.Open(regServ);
        view.AddDeviceL(*newDev,stat);
    });
    User::WaitForRequest(stat);
    stat.Int();
    view.Close();
    regServ.Close();
    SafeDelete(newDev);
}
catch(char* str)
{
    return false;
}

return true;
}

TBool QBtLocalDevicePrivate::DeleteDevice(const QBtAddress& address)
{
    return DeleteOrUnpairDevice(address, false);
}

TBool QBtLocalDevicePrivate::UnpairDevice(const QBtAddress& address)
{
    return DeleteOrUnpairDevice(address, true);
}

TBool QBtLocalDevicePrivate::DeleteOrUnpairDevice(const QBtAddress& address, TBool unpair)
{
    RBTRegServ regServ;
    RBTRegistry view;

    if( regServ.Connect() != KErrNone)
        return false;

    if( view.Open(regServ) != KErrNone)
    {
        regServ.Close();
        return false;
    }

    TBTRegistrySearch search;
    //the bd_addr of the device to be deleted
    QBtAddress nonConstAddress = address;
    search.FindAddress(nonConstAddress.convertToSymbianBtDevAddr());
    TRequestStatus stat;
    view.CreateView(search,stat);
    User::WaitForRequest(stat);

    if(stat.Int() != KErrNone)
    {
        regServ.Close();
        return false;
    }
    if(unpair)
        view.UnpairAllInView(stat);
    else
        view.DeleteAllInView(stat);
    User::WaitForRequest(stat);

    if(stat.Int() != KErrNone)
    {
        regServ.Close();
        return false;
    }

    return true;
}