Join Now
Quality Rating:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)
Expertise Level:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)

This page was last modified 09:39, 2 May 2008.

CS000939 - Establishing a Bluetooth connection

From Forum Nokia Wiki


ID CS000939 Creation date May 2, 2008
Platform S60 3rd Edition, MR Tested on devices Nokia N95
Category Symbian C++ Subcategory Bluetooth


Keywords (APIs, classes, methods, functions): RSocket, TBTServiceSecurity, TSockXfrLength

Overview

The following code example listens to an advertised (KBT_serviceID=0x10ff) Bluetooth connection and reads or send data throught it. Advertising a certain Bluetooth service is explained in CS000938 - Advertising Bluetooth services.

MMP file

The following capabilities and libraries are required:

CAPABILITY  LocalServices NetworkServices
LIBRARY     esock.lib
LIBRARY     bluetooth.lib
LIBRARY     btmanclient.lib

Header file

Bluetooth connection listener.

#include <e32base.h>
#include <bt_sock.h>
 
const TInt KReceivedBufferSize = 40;
const TInt KSizeOfListenQueue = 5; 
_LIT(KRfComm,"RFCOMM");
 
// The service id that identifies the service. This id will be 
// used when advertising the service and discovering the service.
#define KBT_serviceID 0x10ff
 
class CBluetoothListener : public CActive
{
public:
    static CBluetoothListener* NewL(RSocketServ& aSocketServ);
    static CBluetoothListener* NewLC(RSocketServ& aSocketServ);
    ~CBluetoothListener();
 
    void StartListenerL(TInt& aChannel);
    void StopListener();
    void SendData(const TDesC8& aData);
    TBool IsConnected();
 
protected: // From CActive
    void RunL();
    void DoCancel();
    TInt RunError(TInt aError);
    
private:
    CBluetoothListener(RSocketServ& aSocketServ);
    void ConstructL();
    void ReceiveData();
 
public: // data
 
    // Listening socket
    RSocket iListenSock;
 
    // Accepted socket
    RSocket iSock;
 
    // Length of received data
    TSockXfrLength iLen;
 
    // Buffer holding received data
    TBuf8<KReceivedBufferSize> iBuffer;
 
    // Socket server handle
    RSocketServ& iSocketServ;
 
    // Listener connection status
    TBool iIsConnected;
 
    // State of the listener
    enum TState
        {
        ENone = 1,
        EConnecting,
        EWaiting,
        ESending
        };
    TState iState;
};

Source file

CBluetoothListener* CBluetoothListener::NewL(RSocketServ& aSocketServ)
    {
    CBluetoothListener* self = CBluetoothListener::NewLC(aSocketServ);
    CleanupStack::Pop(self);
    return self;
    }
 
 
CBluetoothListener* CBluetoothListener::NewLC(RSocketServ& aSocketServ)
    {
    CBluetoothListener* self = new (ELeave) CBluetoothListener(aSocketServ);
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
    }
 
void CBluetoothListener::ConstructL()
    {
    }
 
CBluetoothListener::CBluetoothListener(RSocketServ& aSocketServ):
    CActive(CActive::EPriorityStandard),
    iSocketServ(aSocketServ),
    iIsConnected(EFalse),
    iState(ENone)
    {
    CActiveScheduler::Add(this);
    }
 
CBluetoothListener::~CBluetoothListener()
    {
    Cancel();
    StopListener();
    }
 
void CBluetoothListener::StartListenerL(TInt& aChannel)
    {
    if ( iState!=ENone )
        {
        User::Leave(KErrInUse);
        }
 
    // Set this active object to connecting state
    iState=EConnecting;
 
    // Load protocol, RFCOMM
    TProtocolDesc pdesc;
    User::LeaveIfError(iSocketServ.FindProtocol(KRfComm(), pdesc));
 
    // Open a socket
    User::LeaveIfError(
        iListenSock.Open(iSocketServ,
        pdesc.iAddrFamily,pdesc.iSockType,KRFCOMM)
        );
 
    // Get listening channel
    User::LeaveIfError(iListenSock.GetOpt(KRFCOMMGetAvailableServerChannel, 
        KSolBtRFCOMM, aChannel));
    
    // Bluetooth socket address object
    TBTSockAddr btsockaddr;
    btsockaddr.SetPort(aChannel);
 
    // Bind bluetooth socket
    User::LeaveIfError(iListenSock.Bind(btsockaddr));
 
    // Listen on port
    iListenSock.Listen(KSizeOfListenQueue);
    
    // Set security
    TBTServiceSecurity secSettings;    
    TUid settingsUID;
    settingsUID.iUid = KBT_serviceID;
    secSettings.SetUid(settingsUID);
    secSettings.SetAuthentication(EFalse);
    secSettings.SetAuthorisation(EFalse);
    secSettings.SetEncryption(EFalse);
    
    // Attach the security settings.
    btsockaddr.SetSecurity(secSettings);
 
    // 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);
    SetActive();
    }
 
void CBluetoothListener::StopListener()
    {
    if ( iState!=ENone )
        {       
        iSock.Close();
        iListenSock.Close();
        iState=ENone;
        }
    }
 
void CBluetoothListener::ReceiveData()
    {
    // 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 CBluetoothListener::SendData(const TDesC8& aData)
    {
    if ( iState!=EWaiting )
        return;
    // Cancel any read requests on socket
    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(aData, iStatus);
    // - start waiting async req response (iState) from active scheduler
    SetActive();
    }
 
void CBluetoothListener::RunL()
    {
    if ( iStatus!=KErrNone )
        {
        StopListener();
        TODO: Add error handling
        return;
        }
    
    switch (iState)
        {
        case EConnecting:
            {
            // Connected listening socket!
            ReceiveData();
            break;
            }
        case EWaiting:
            {
            // Returned from receiving data
            if(iState!=KErrNone)
                {
                // add the error handling / re-reading code here..
                // not needed in this example
                }
 
            HBufC* text = HBufC::NewLC(iBuffer.Length());
            text->Des().Copy(iBuffer);
            // TODO: Do something with received data
            CleanupStack::PopAndDestroy(text);
 
            // Start expecting next data to be read
            ReceiveData();
            break;
            }
        case ESending:
            {
            // Returned from sending the date, check the state
            if(iState!=KErrNone)
                {
                // add the error handling / re-sending code here..
                // not needed in this example
                }
 
            // Start expecting next data to be read
            ReceiveData();
            break;
            }
        default:
            break;
        }
    }
 
TInt CBluetoothListener::RunError(TInt aError)
    {
    // TODO: Add the error handling
    return KErrNone;
    }
 
void CBluetoothListener::DoCancel()
    {
    iSock.CancelAll();
    iListenSock.CancelAll();
    }
 
TBool CBluetoothListener::IsConnected()
    {
    return iIsConnected;
    }


See also

CS000936 - Discovering Bluetooth devices

CS000937 - Discovering Bluetooth services

CS000938 - Advertising Bluetooth services

KIS000330 - RHostResolver and redundant display of access point selection dialog

Example application

This code snippet has been used in the S60 Platform: Bluetooth Point-to-multipoint Example application.

Related Discussions
Thread Thread Starter Forum Replies Last Post
connection selection use MIDP paulcji Mobile Java General 0 2003-12-23 16:05
TCP/IP over bluetooth hakanakerberg Bluetooth Technology 0 1970-01-01 02:00
More about Bluetooth traffic on PC gigidg Bluetooth Technology 0 2003-09-18 14:28
6600 Bluetooth Serial connection issues Saiyan_Trb Bluetooth Technology 3 2004-09-21 08:26
Expensive connections vilents Mobile Java General 0 1970-01-01 02:00
 
Powered by MediaWiki