S60 3rd Edition SDK for Symbian OS
Example Applications Guide

CChatBt Class Reference

#include <ChatBt.h>

Inheritance diagram for CChatBt:

CChatBase List of all members.

Public Member Functions

virtual ~CChatBt ()
void ConnectL ()
void DisconnectL ()
void SendMessageL (TDes &aText)
void StartL ()
void StopL ()

Static Public Member Functions

static CChatBt * NewL (MLog &aLog)
static CChatBt * NewLC (MLog &aLog)

Protected Member Functions

void DoCancel ()
void RunL ()

Private Member Functions

void ConnectToServerL ()
void DisconnectFromServerL ()
 CChatBt (MLog &aLog)
void ConstructL ()
void RequestData ()
void SetSecurityWithChannelL (TBool aAuthentication, TBool aEncryption, TBool aAuthorisation, TBool aDenied, TInt &aChannel)

Static Private Member Functions

static void SetSecurityOnChannelL (TBool aAuthentication, TBool aEncryption, TBool aAuthorisation, TInt aChannel)

Private Attributes

CChatServiceSearcher * iServiceSearcher
MLog & iLog
HBufC8 * iMessage
RSocketServ iSocketServer
RSocket iSocket
TUUID iServiceClass
TBuf8< KChatTextBufLength > iBuffer
CChatServiceAdvertiser * iAdvertiser
RSocket iAcceptedSocket
TSockXfrLength iLen
RSocket * iActiveSocket

Detailed Description

CChatBt Connects and sends messages to a remote machine using bluetooth

Definition at line 35 of file ChatBt.h.


Constructor & Destructor Documentation

CChatBt::~CChatBt (   )  [virtual]
 

~CChatBt() Destroy the object and release all memory objects. Close any open sockets.

Definition at line 70 of file ChatBt.cpp.

References iAcceptedSocket, iActiveSocket, iAdvertiser, iMessage, iServiceSearcher, iSocket, iSocketServer, and CChatBase::State().

00071     {
00072     // Close() will wait forever for Read to complete
00073     if ( State() == EConnected )
00074         {
00075         if ( iActiveSocket )
00076             {
00077             iActiveSocket->CancelRead();
00078             }
00079         }
00080     Cancel();
00081 
00082     iSocket.Close();
00083     iAcceptedSocket.Close();
00084     iSocketServer.Close();
00085 
00086     delete iMessage;
00087     iMessage = NULL;
00088 
00089     delete iServiceSearcher;
00090     iServiceSearcher = NULL;
00091     
00092     delete iAdvertiser;
00093     iAdvertiser = NULL;
00094     }

CChatBt::CChatBt (  MLog &  aLog  )  [private]
 

CChatBt() Constructs this object

Parameters:
aLog the log to send output to

Definition at line 58 of file ChatBt.cpp.

References CChatBase::SetState().

00058                              : 
00059     CChatBase( aLog ),
00060     iLog( aLog )
00061     {
00062     SetState( EWaitingToGetDevice );
00063     }


Member Function Documentation

CChatBt * CChatBt::NewL (  MLog &  aLog  )  [static]
 

NewL() Construct a CChatBt

Parameters:
aLog the log to send output to
Returns:
a pointer to the created instance of CChatBt

Reimplemented from CChatBase.

Definition at line 33 of file ChatBt.cpp.

References NewLC().

00034     {
00035     CChatBt* self = NewLC( aLog );
00036     CleanupStack::Pop( self );
00037     return self;
00038     }

CChatBt * CChatBt::NewLC (  MLog &  aLog  )  [static]
 

NewLC() Construct a CChatBt

Parameters:
aLog the log to send output to
Returns:
a pointer to the created instance of CChatBt

Reimplemented from CChatBase.

Definition at line 45 of file ChatBt.cpp.

References CChatBt().

00046     {
00047     CChatBt* self = new ( ELeave ) CChatBt( aLog );
00048     CleanupStack::PushL( self );
00049     self->ConstructL();
00050     return self;
00051     }

void CChatBt::ConnectL (   ) 
 

ConnectL() Connect to an available service on a remote machine

Definition at line 314 of file ChatBt.cpp.

References iLog, iServiceSearcher, MLog::LogL(), CChatBtServiceSearcher::SelectDeviceByDiscoveryL(), CChatBase::SetState(), and CChatBase::State().

00315     {
00316     if ( State() == EWaitingToGetDevice && !IsActive() )
00317         {
00318         SetState( EGettingDevice );
00319         iServiceSearcher->SelectDeviceByDiscoveryL( iStatus );
00320         SetActive();
00321         }
00322     else
00323         {
00324         HBufC* errClientBusy = StringLoader::LoadLC ( R_CHAT_CLIENT_BUSY );
00325         iLog.LogL( *errClientBusy );
00326         CleanupStack::PopAndDestroy( errClientBusy );
00327 
00328         User::Leave( KErrInUse );
00329         }
00330     }

void CChatBt::DisconnectL (   ) 
 

DisconnectL() Disconnect from remote machine

Definition at line 337 of file ChatBt.cpp.

References DisconnectFromServerL(), iLog, MLog::LogL(), CChatBase::SetState(), and CChatBase::State().

00338     {
00339     if ( ( State() == EConnected )||( State() == ESendingMessage ) )
00340         {
00341         DisconnectFromServerL();
00342         SetState( EDisconnecting );
00343         }
00344     else
00345         {
00346         HBufC* errNoConn = StringLoader::LoadLC ( R_CHAT_ERR_NO_CONN );
00347         iLog.LogL( *errNoConn );
00348         CleanupStack::PopAndDestroy( errNoConn );
00349         User::Leave( KErrDisconnected );
00350         }
00351     }

void CChatBt::SendMessageL (  TDes &  aText  ) 
 

SendMessageL() Sends a message to a service on a remote machine.

Parameters:
aText Text to send

Definition at line 408 of file ChatBt.cpp.

References iActiveSocket, iMessage, CChatBase::SetState(), and CChatBase::State().

00409     {
00410 
00411     if ( State() != EConnected )
00412         {
00413         User::Leave( KErrDisconnected );
00414         }
00415 
00416     // stop reading socket
00417     if ( iActiveSocket )
00418         {
00419         iActiveSocket->CancelRead();
00420         }
00421 
00422     if ( IsActive() )
00423         {
00424         Cancel();
00425         }
00426     TBufC<KChatTextBufLength> message ( aText );
00427     SetState( ESendingMessage );
00428     HBufC* tempString = HBufC::NewL( message.Length() );
00429     CleanupStack::PushL( tempString );
00430     tempString->Des().Copy( message );
00431     
00432     iMessage = HBufC8::NewL(tempString->Length());
00433     CleanupStack::Pop( tempString );
00434     iMessage->Des().Copy( *tempString );
00435     
00436     if ( iActiveSocket )
00437         {
00438         iActiveSocket->Write( *iMessage, iStatus );
00439         }
00440 
00441     delete tempString;
00442     
00443     SetActive();
00444     }

void CChatBt::StartL (   ) 
 

StartL() Start server and waiting for connection.

Definition at line 453 of file ChatBt.cpp.

References iAdvertiser, iSocket, iSocketServer, SetSecurityWithChannelL(), CChatBase::SetServer(), CChatBtServiceAdvertiser::StartAdvertisingL(), CChatBase::State(), and CChatBtServiceAdvertiser::UpdateAvailabilityL().

00454     {
00455     if ( State() != EWaitingToGetDevice )
00456         {
00457         User::Leave( KErrInUse );
00458         }
00459 
00460     TInt result( 0 );
00461     result = iSocket.Open( iSocketServer, KStrRFCOMM );
00462     if ( result != KErrNone )
00463         {
00464         iSocketServer.Close();
00465         User::Leave( result ); 
00466         }
00467 
00468    
00469     // 
00470     // Set the Socket's security with parameters, 
00471     // Authentication, Encryption, Authorisation and Denied
00472     // Method also return the channel available to listen to. 
00473     TInt channel;
00474     SetSecurityWithChannelL( EFalse, EFalse, ETrue, EFalse, channel );
00475 
00476     iAdvertiser->StartAdvertisingL( channel );
00477     iAdvertiser->UpdateAvailabilityL( ETrue );
00478     
00479     SetServer( ETrue );
00480 
00481     }

void CChatBt::StopL (   ) 
 

StopL() Stop server.

Definition at line 565 of file ChatBt.cpp.

References iAcceptedSocket, iActiveSocket, iAdvertiser, CChatBtServiceAdvertiser::IsAdvertising(), iSocket, CChatBase::State(), and CChatBtServiceAdvertiser::StopAdvertisingL().

00566     {
00567     if ( State() != EDisconnected )
00568         {
00569         if ( iAdvertiser->IsAdvertising() )
00570             {
00571             iAdvertiser->StopAdvertisingL();
00572             }
00573         // Close() will wait forever for Read to complete
00574         if ( State() == EConnected )
00575             {
00576             if ( iActiveSocket )
00577                 {
00578                 iActiveSocket->CancelRead();
00579                 }
00580             }    
00581         iAcceptedSocket.Close();
00582         iSocket.Close();
00583         }
00584         SetState( EWaitingToGetDevice );
00585     }

void CChatBt::DoCancel (   )  [protected]
 

DoCancel() Cancel any outstanding requests

Reimplemented from CChatBase.

Definition at line 113 of file ChatBt.cpp.

00114     {
00115     // no implementation required
00116     }

void CChatBt::RunL (   )  [protected]
 

RunL() Respond to an event

Reimplemented from CChatBase.

Definition at line 123 of file ChatBt.cpp.

References ConnectToServerL(), DisconnectFromServerL(), CChatBtServiceSearcher::FindServiceL(), iAdvertiser, iBuffer, iLog, iServiceSearcher, iSocket, MLog::LogL(), RequestData(), CChatBtServiceSearcher::ResponseParams(), CChatBase::SetState(), CChatBase::State(), StopL(), and CChatBtServiceAdvertiser::UpdateAvailabilityL().

00124     {
00125 
00126     HBufC* textResource = NULL;
00127     TBuf<KMaxMarkLen> mark;
00128   
00129     if ( iStatus == KErrDisconnected )
00130         {
00131         // Disconnected
00132         HBufC* strDisconnected = StringLoader
00133             ::LoadLC ( R_CHAT_STR_DISCONNECTED );
00134         iLog.LogL( *strDisconnected );
00135         CleanupStack::PopAndDestroy( strDisconnected );
00136         StopL();
00137         return;
00138         }
00139         
00140     else if ( iStatus == KErrAbort )
00141         {
00142         HBufC* strDisconnected = StringLoader
00143             ::LoadLC ( R_CHAT_STR_DISCONNECTED );
00144         iLog.LogL( *strDisconnected );
00145         CleanupStack::PopAndDestroy( strDisconnected );
00146         StopL();
00147         return;
00148         }
00149   
00150     else if ( iStatus != KErrNone )
00151         {
00152         switch ( State() )
00153             {
00154             case EGettingDevice:
00155                 if ( iStatus == KErrCancel )
00156                     {
00157                     textResource = StringLoader
00158                         ::LoadLC( R_CHAT_ERR_NO_DEVICE_SELECTED );
00159                     iLog.LogL( *textResource );
00160                     CleanupStack::PopAndDestroy( textResource );
00161                     }
00162                 SetState( EWaitingToGetDevice );
00163                 break;
00164                 
00165             case EGettingService:
00166             
00167             case EGettingConnection:
00168                 textResource = StringLoader
00169                     ::LoadLC( R_CHAT_ERR_CONNECTION_ERROR );
00170                 iLog.LogL( *textResource, iStatus.Int() );
00171                 CleanupStack::PopAndDestroy( textResource );
00172                 SetState( EWaitingToGetDevice );
00173                 break;
00174                 
00175             case EConnected:
00176                 textResource = StringLoader
00177                     ::LoadLC( R_CHAT_ERR_LOST_CONNECTION );
00178                 iLog.LogL( *textResource, iStatus.Int() );
00179                 DisconnectFromServerL();
00180                 CleanupStack::PopAndDestroy( textResource );
00181                 SetState( EDisconnecting );
00182                 break;
00183                 
00184             case ESendingMessage:
00185                 textResource = StringLoader
00186                     ::LoadLC( R_CHAT_ERR_MESSAGE_FAILED );
00187                 iLog.LogL( *textResource, iStatus.Int() );
00188                 CleanupStack::PopAndDestroy( textResource );
00189                 DisconnectFromServerL();
00190                 SetState( EDisconnecting );
00191                 break;
00192                 
00193             case EDisconnecting:
00194                 if ( iStatus == KErrDisconnected )
00195                     {
00196                     textResource = StringLoader
00197                         ::LoadLC( R_CHAT_DISCONNECT_COMPLETE );
00198                     iLog.LogL( *textResource, iStatus.Int() );
00199                     CleanupStack::PopAndDestroy( textResource );
00200 
00201                     StopL();
00202                     SetState( EWaitingToGetDevice );
00203                     }
00204                 else
00205                     {
00206                     textResource = StringLoader
00207                         ::LoadLC( R_CHAT_ERR_FAILED_TO_DISCONNECT );
00208                     iLog.LogL( *textResource, iStatus.Int() );
00209                     CleanupStack::PopAndDestroy( textResource );
00210 
00211                     Panic( EChatUnableToDisconnect );
00212                     }
00213                 break;
00214             
00215             case EWaitingToGetDevice:
00216                 textResource = StringLoader
00217                     ::LoadLC( R_CHAT_STR_DISCONNECTED );
00218                 iLog.LogL( *textResource );
00219                 CleanupStack::PopAndDestroy( textResource );
00220                 break;
00221                 
00222             default:
00223                 Panic( EChatInvalidLogicState );
00224                 break;
00225             }
00226         }
00227         
00228     else 
00229         {
00230         switch ( State() )
00231             {
00232             case EGettingDevice:
00233                 // found a device now search for a suitable service
00234                 iLog.LogL( iServiceSearcher->ResponseParams().DeviceName() );
00235                 SetState( EGettingService );
00236                 iStatus = KRequestPending;  // this means that the RunL 
00237                                             // can not be called until
00238                                             // this program does something 
00239                                             // to iStatus
00240                 iServiceSearcher->FindServiceL( iStatus );
00241                 SetActive();
00242                 break;
00243                 
00244             case EConnecting:
00245                 textResource = StringLoader::LoadLC ( R_CHAT_CONNECTED );
00246                 iLog.LogL( *textResource );
00247                 CleanupStack::PopAndDestroy( textResource );
00248               
00249                 // do not accept any more connections
00250                 iAdvertiser->UpdateAvailabilityL( EFalse );
00251                 RequestData();
00252                 SetState( EConnected );
00253                 break;
00254                 
00255             case EGettingService:
00256                 textResource = StringLoader
00257                     ::LoadLC( R_CHAT_FOUND_SERVICE );
00258                 iLog.LogL( *textResource );
00259                 CleanupStack::PopAndDestroy( textResource );
00260                 SetState( EGettingConnection );
00261                 ConnectToServerL();
00262                 break;
00263                 
00264             case EGettingConnection:
00265                 textResource = StringLoader
00266                     ::LoadLC( R_CHAT_CONNECTED );
00267                 iLog.LogL( *textResource );
00268                 CleanupStack::PopAndDestroy( textResource );
00269                 SetState( EConnected );
00270                 RequestData();
00271                 break;
00272                 
00273             case EConnected:
00274               
00275                 mark.Append( '>' );
00276                 textResource = HBufC::NewLC( iBuffer.Length() );
00277                 textResource->Des().Copy( iBuffer );
00278                 iLog.LogL( *textResource, mark );
00279                 iBuffer.Zero();
00280                 CleanupStack::PopAndDestroy( textResource );
00281                 RequestData();
00282                 break;
00283                 
00284             case ESendingMessage:
00285                 SetState( EConnected );
00286                 RequestData();
00287                 break;
00288                 
00289             case EDisconnecting:
00290                 textResource = StringLoader
00291                     ::LoadLC( R_CHAT_DISCONNECT_COMPLETE );
00292                 iLog.LogL( *textResource );
00293                 CleanupStack::PopAndDestroy ( textResource );
00294                 iSocket.Close();
00295                 SetState( EWaitingToGetDevice );
00296                 break;
00297             
00298             case EWaitingToGetDevice:
00299                 
00300                 break;
00301                 
00302             default:
00303                 Panic( EChatInvalidLogicState );
00304                 break;
00305             };
00306         }
00307     }

void CChatBt::ConnectToServerL (   )  [private]
 

ConnectToServerL Connects to the service

Definition at line 377 of file ChatBt.cpp.

References CChatBtServiceSearcher::BTDevAddr(), iActiveSocket, iLog, iServiceSearcher, iSocket, iSocketServer, MLog::LogL(), and CChatServiceSearcher::Port().

00378     {
00379     HBufC* strConnecting = StringLoader
00380         ::LoadLC ( R_CHAT_STR_CONNECTING );
00381     iLog.LogL( *strConnecting );
00382     CleanupStack::PopAndDestroy( strConnecting );
00383 
00384     User::LeaveIfError( iSocket.Open( iSocketServer, KStrRFCOMM ) );
00385 
00386     TBTSockAddr address;
00387     address.SetBTAddr( iServiceSearcher->BTDevAddr() );
00388     address.SetPort( iServiceSearcher->Port() );
00389 
00390     iSocket.Connect( address, iStatus );
00391   
00392     iActiveSocket = &iSocket;
00393   
00394     #ifdef __WINS__
00395         // Fix to allow emulator client to connect to server
00396         User::After( 1 );     
00397     #endif
00398   
00399     SetActive();
00400     }

void CChatBt::DisconnectFromServerL (   )  [private]
 

DisonnectFromServerL() Disconnects from the service

Definition at line 358 of file ChatBt.cpp.

References iLog, iSocket, and MLog::LogL().

00359     {
00360     // Terminate all operations
00361     iSocket.CancelAll();
00362     Cancel();
00363 
00364     HBufC* strReleasingConn = StringLoader
00365         ::LoadLC ( R_CHAT_STR_RELEASING_CONN );
00366     iLog.LogL( *strReleasingConn );
00367     CleanupStack::PopAndDestroy( strReleasingConn );
00368     iSocket.Shutdown( RSocket::ENormal, iStatus );
00369     SetActive();
00370     }

void CChatBt::ConstructL (   )  [private]
 

ConstructL() Performs second phase construction of this object

Reimplemented from CChatBase.

Definition at line 101 of file ChatBt.cpp.

References iAdvertiser, iLog, iServiceSearcher, iSocketServer, CChatServiceAdvertiser::NewL(), and CChatServiceSearcher::NewL().

00102     {
00103     iServiceSearcher = CChatServiceSearcher::NewL( iLog );
00104     iAdvertiser = CChatServiceAdvertiser::NewL();
00105     User::LeaveIfError( iSocketServer.Connect() );
00106     }

void CChatBt::RequestData (   )  [private]
 

RequestData() Request data from the client, this object is notified when data becomes available

Definition at line 592 of file ChatBt.cpp.

References iActiveSocket, iBuffer, and iLen.

00593     {
00594     if ( iActiveSocket )
00595         {
00596         iActiveSocket->RecvOneOrMore( iBuffer, 0, iStatus, iLen );
00597         }
00598     SetActive();
00599     }

void CChatBt::SetSecurityWithChannelL (  TBool  aAuthentication,
TBool  aEncryption,
TBool  aAuthorisation,
TBool  aDenied,
TInt &  aChannel
)  [private]
 

SetSecurityWithChannelL Sets the security on the channel port And returns the channel available.

Parameters:
aAuthentication is authentication used
aEncryption is encryption used
aAuthorisation is authorisation used
aDenied is denied used
Returns:
an available channel

Definition at line 488 of file ChatBt.cpp.

References iAcceptedSocket, iActiveSocket, iLog, iSocket, iSocketServer, MLog::LogL(), and CChatBase::SetState().

00495     {
00496 
00497     // Local variable to channel to listen to.
00498     TInt channel;
00499 
00500 
00501     User::LeaveIfError( iSocket.GetOpt( 
00502         KRFCOMMGetAvailableServerChannel, 
00503         KSolBtRFCOMM, 
00504         channel ) );
00505 
00506     TBTSockAddr listeningAddress;
00507     // Set the Port to listen to.
00508     listeningAddress.SetPort( channel );
00509 
00510     // Write Log events
00511     HBufC* strGetPort = StringLoader::LoadLC ( R_CHAT_STR_GET_PORT );
00512 
00513     iLog.LogL( *strGetPort, channel );
00514     CleanupStack::PopAndDestroy( strGetPort );
00515 
00516 
00517     User::LeaveIfError( iSocket.Bind( listeningAddress ) );
00518     User::LeaveIfError( iSocket.Listen( KListeningQueSize ) );
00519 
00520      // close old connection - if any
00521     iAcceptedSocket.Close();
00522 
00523     // Open abstract socket
00524     User::LeaveIfError( iAcceptedSocket.Open( iSocketServer ) );  
00525 
00526     // Set the Active Object's State to Connecting indicated.
00527     SetState( EConnecting );
00528 
00529     iSocket.Accept( iAcceptedSocket, iStatus );
00530   
00531     iActiveSocket = &iAcceptedSocket;
00532   
00533     // Set the Active Object Active again,
00534     SetActive();
00535 
00536     // Write Log events
00537     HBufC* acceptNextConn = StringLoader::LoadLC ( 
00538         R_CHAT_ACCEPT_NEXT_CONN );
00539     iLog.LogL( *acceptNextConn );
00540     CleanupStack::PopAndDestroy( acceptNextConn );
00541 
00542  
00543     // Set the security according to.
00544     TBTServiceSecurity serviceSecurity;
00545     serviceSecurity.SetUid ( KUidChatApp );
00546     serviceSecurity.SetAuthentication ( aAuthentication );
00547     serviceSecurity.SetEncryption ( aEncryption );
00548     serviceSecurity.SetAuthorisation ( aAuthorisation );
00549     serviceSecurity.SetDenied( aDenied );
00550 
00551     // Attach the security settings.
00552     listeningAddress.SetSecurity(serviceSecurity);
00553 
00554     // Return the port to listen to.
00555     aChannel = channel;
00556   
00557     }

static void CChatBt::SetSecurityOnChannelL (  TBool  aAuthentication,
TBool  aEncryption,
TBool  aAuthorisation,
TInt  aChannel
)  [static, private]
 

SetSecurityOnChannelL() Sets the security on the channel port

Parameters:
aAuthentication is authentication used
aEncryption is encryption used
aAuthorisation is authorisation used
aChannel used channel ID


Member Data Documentation

CChatServiceSearcher* CChatBt::iServiceSearcher [private]
 

iServiceSearcher searches for service this client can connect to. Owned by CChatBt

Definition at line 183 of file ChatBt.h.

MLog& CChatBt::iLog [private]
 

iLog the log to send output to

Reimplemented from CChatBase.

Definition at line 189 of file ChatBt.h.

HBufC8* CChatBt::iMessage [private]
 

iMessage a copy of the message to send Owned by CChatBt

Definition at line 195 of file ChatBt.h.

RSocketServ CChatBt::iSocketServer [private]
 

iSocketServer a connection to the socket server

Definition at line 201 of file ChatBt.h.

RSocket CChatBt::iSocket [private]
 

iSocket a socket to connect with

Definition at line 207 of file ChatBt.h.

TUUID CChatBt::iServiceClass [private]
 

iServiceClass the service class UUID to search for

Definition at line 213 of file ChatBt.h.

TBuf8<KChatTextBufLength> CChatBt::iBuffer [private]
 

iBuffer the buffer to read data to

Definition at line 219 of file ChatBt.h.

CChatServiceAdvertiser* CChatBt::iAdvertiser [private]
 

iAdvertiser used to advertise this service Owned by CChatServer

Definition at line 225 of file ChatBt.h.

RSocket CChatBt::iAcceptedSocket [private]
 

iAcceptedSocket the socket that connections are accepted to

Definition at line 231 of file ChatBt.h.

TSockXfrLength CChatBt::iLen [private]
 

iLen length of data read

Definition at line 237 of file ChatBt.h.

RSocket* CChatBt::iActiveSocket [private]
 

iActiveSocket the active socket

Definition at line 243 of file ChatBt.h.


© Nokia 2006

Back to top