examples/ForumNokia/BluetoothPMPExample/src/Listener.cpp

00001 /*
00002  * Copyright © 2009 Nokia Corporation.
00003  */
00004 
00005 // INCLUDE FILES
00006 #include "Listener.h"
00007 #include "BluetoothPMPExampleApp.h"
00008 
00009 
00010 CListener* CListener::NewL(MListenerObserver& aObserver, 
00011                            RSocketServ& aSocketServ)
00012     {
00013     CListener* self = CListener::NewLC(aObserver, aSocketServ);
00014     CleanupStack::Pop(self);
00015     return self;
00016     }
00017 
00018 
00019 CListener* CListener::NewLC(MListenerObserver& aObserver,
00020                             RSocketServ& aSocketServ)
00021     {
00022     CListener* self = new (ELeave) CListener(aObserver, aSocketServ);
00023     CleanupStack::PushL(self);
00024     self->ConstructL();
00025     return self;
00026     }
00027 
00028 
00029 void CListener::ConstructL()
00030     {
00031     }
00032 
00033 
00034 // ----------------------------------------------------------------------------
00035 // CListener::CListener(MListernetObserver* aObserver,
00036 //                      RSocketServ *aSocketServ)
00037 //
00038 // constructor
00039 // ----------------------------------------------------------------------------
00040 CListener::CListener(MListenerObserver& aObserver, 
00041                      RSocketServ& aSocketServ):
00042     CActive(CActive::EPriorityStandard),
00043     iObserver(aObserver),
00044     iSocketServ(aSocketServ),
00045     iIsConnected(EFalse),
00046     iState(ENone)
00047     {
00048     CActiveScheduler::Add(this);
00049     }
00050 
00051 
00052 // ----------------------------------------------------------------------------
00053 // CListener::~CListener()
00054 //
00055 // destructor
00056 // ----------------------------------------------------------------------------
00057 CListener::~CListener()
00058     {
00059     // cancel active object
00060     Cancel();
00061     // close sockets
00062     StopListener();
00063     }
00064 
00065 
00066 // ----------------------------------------------------------------------------
00067 // CListener::StartListenerL()
00068 //
00069 // start listener.  listener will open a listening socket on a channel (port)
00070 // gotten from GetOpt() call.  
00071 // ----------------------------------------------------------------------------
00072 void CListener::StartListenerL(TInt& aChannel)
00073     {
00074     // get out if we're already running..
00075     if ( iState!=ENone )
00076         {
00077         User::Leave(KErrInUse);
00078         }
00079 
00080     // set this active object to connecting state
00081     iState=EConnecting;
00082 
00083     // load protocol, RFCOMM
00084     TProtocolDesc pdesc;
00085     User::LeaveIfError(iSocketServ.FindProtocol(KRfComm(), pdesc));
00086 
00087     // open a socket
00088     User::LeaveIfError(
00089         iListenSock.Open(iSocketServ,
00090         pdesc.iAddrFamily,pdesc.iSockType,KRFCOMM)
00091         );
00092 
00093     // get listening channel
00094     User::LeaveIfError(iListenSock.GetOpt(KRFCOMMGetAvailableServerChannel, 
00095         KSolBtRFCOMM, aChannel));
00096     
00097     // bluetooth socket address object
00098     TBTSockAddr btsockaddr;
00099     btsockaddr.SetPort(aChannel);
00100     // bind socket
00101     User::LeaveIfError(iListenSock.Bind(btsockaddr));
00102     // listen on port
00103     iListenSock.Listen(KSizeOfListenQueue);
00104     
00105     //now set security
00106     
00107     //old way to set security is in Listener.cpp
00108     //CListener::SetSecurityL(TInt aChannel)
00109     TBTServiceSecurity secSettings;    
00110     
00111     TUid settingsUID;
00112     settingsUID.iUid = KBT_serviceID;
00113     secSettings.SetUid(settingsUID);
00114     //the old way involved the following two steps:
00115     //secSettings.SetChannelID(aChannel);
00116     //secSettings.SetProtocolID(KSolBtRFCOMM);
00117     secSettings.SetAuthentication(EFalse);
00118     secSettings.SetAuthorisation(EFalse);
00119     secSettings.SetEncryption(EFalse);
00120     
00121     // attach the security settings.
00122     btsockaddr.SetSecurity(secSettings);
00123 
00124     // close old accepted socket if open
00125     iSock.Close();
00126 
00127     // open blank socket and pass it to accept to be assigned a proper
00128     // socket upon completion of Accept()
00129     User::LeaveIfError(iSock.Open(iSocketServ));
00130 
00131     // set to accept incoming connections, active object will handle
00132     iListenSock.Accept(iSock,iStatus);
00133     SetActive();
00134     }
00135 
00136 
00137 // ----------------------------------------------------------------------------
00138 // CListener::SetSecurityL(TInt aChannel)
00139 //
00140 // sets the security of given bluetooth channel.  these settings will turn
00141 // off authentication, authorisation and encryption on given channel.
00142 // 
00143 // Not supported in 2nd ed. FP2 and newer versions.
00144 // Left here just for comparing.
00145 // ----------------------------------------------------------------------------
00146 void CListener::SetSecurityL(TInt /*aChannel*/)
00147     {
00148     //this is not supported in 2nd ed. FP2 and above:
00149     //setup channel security:
00150     //TRequestStatus status;
00151     //RBTMan secManager;
00152 
00153     //RBTSecuritySettings secDatabase;
00154     //TBTServiceSecurity secSettings;
00155     // connect to security manager
00156     //User::LeaveIfError(secManager.Connect());
00157     //CleanupClosePushL(secManager);
00158     //User::LeaveIfError(secDatabase.Open(secManager));
00159     //CleanupClosePushL(secDatabase);
00160     // setup security
00161     //TUid settingsUID;
00162     //settingsUID.iUid = KBT_serviceID;
00163     //secSettings.SetUid(settingsUID);
00164     //secSettings.SetChannelID(aChannel);
00165     //secSettings.SetProtocolID(KSolBtRFCOMM);
00166     //secSettings.SetAuthentication(EFalse);
00167     //secSettings.SetAuthorisation(EFalse);
00168     //secSettings.SetEncryption(EFalse);
00169     // register settings with security
00170     //secDatabase.RegisterService(secSettings, status);
00171     //User::WaitForRequest(status);
00172     //CleanupStack::PopAndDestroy(2,&secManager);//SecDatabase, secManager
00173     }
00174 
00175 
00176 // ----------------------------------------------------------------------------
00177 // CListener::StopListener()
00178 //
00179 // stops the listener by closing the listening socket
00180 // ----------------------------------------------------------------------------
00181 void CListener::StopListener()
00182     {
00183     // kill sockets
00184     if ( iState!=ENone )
00185         {       
00186         iSock.Close();
00187         iListenSock.Close();
00188         iState=ENone;
00189         }
00190     }
00191 
00192 
00193 // ----------------------------------------------------------------------------
00194 // CListener::ReceiveData()
00195 //
00196 // receive more data from listening socket, asynchronously.  
00197 // ----------------------------------------------------------------------------
00198 void CListener::ReceiveData()
00199     {
00200     // set state to waiting - for RunL()
00201     iState = EWaiting;
00202     // make async request
00203     iSock.RecvOneOrMore(iBuffer, 0, iStatus, iLen);
00204     // set as active to get the async req response (iState) in RunL()
00205     SetActive();
00206     }
00207 
00208 
00209 // ----------------------------------------------------------------------------
00210 // CListener::SendData(const TDesC8& aData)
00211 //
00212 // send data to remote device, write data to socket.
00213 // ----------------------------------------------------------------------------
00214 void CListener::SendData(const TDesC8& aData)
00215     {
00216     if ( iState!=EWaiting )
00217         return;
00218     // cancel any read requests on socket
00219     Cancel();
00220     // try to send message by writing to socket
00221     // - set the state of this active object to "sending"
00222     iState=ESending;
00223     // - make async socket write request
00224     iSock.Write(aData, iStatus);
00225     // - start waiting async req response (iState) from active scheduler
00226     SetActive();
00227     }
00228 
00229 
00230 void CListener::RunL()
00231     {
00232     if ( iStatus!=KErrNone )
00233         {
00234         StopListener();
00235         HandleListenerDisconnectedL();
00236         return;
00237         }
00238     
00239     switch (iState)
00240         {
00241         case EConnecting:
00242             {
00243             // connected listening socket!
00244             HandleListenerConnectedL();
00245             ReceiveData();
00246             break;
00247             }
00248         case EWaiting:
00249             {
00250             // returned from receiving data
00251             if(iState!=KErrNone)
00252                 {
00253                     // add the error handling / re-reading code here..
00254                     // not needed in this example
00255                 }
00256 
00257             HBufC* text = HBufC::NewLC(iBuffer.Length());
00258             text->Des().Copy(iBuffer);
00259             // observer will handle data
00260             HandleListenerDataReceivedL(*text);
00261             CleanupStack::PopAndDestroy(text);
00262             // start expecting next data to be read
00263             ReceiveData();
00264             break;
00265             }
00266         case ESending:
00267             {
00268             // returned from sending the date, check the state
00269             if(iState!=KErrNone)
00270                 {
00271                     // add the error handling / re-sending code here..
00272                     // not needed in this example
00273                 }
00274 
00275             // start expecting next data to be read
00276             ReceiveData();
00277             break;
00278             }
00279         default:
00280             break;
00281         }
00282     }
00283 
00284 TInt CListener::RunError(TInt /*aError*/)
00285     {
00286     // add the error handling
00287     return KErrNone;
00288     }
00289 
00290 
00291 void CListener::DoCancel()
00292     {
00293     // cancel all pending socket operations
00294     iSock.CancelAll();
00295     iListenSock.CancelAll();
00296     }
00297 
00298 
00299 // ----------------------------------------------------------------------------
00300 // CListener::IsConnected()
00301 //
00302 // returns true if listener has been connected to
00303 // ----------------------------------------------------------------------------
00304 TBool CListener::IsConnected()
00305     {
00306     return iIsConnected;
00307     }
00308 
00309 
00310 // ----------------------------------------------------------------------------
00311 // CListener::HandleListenerDataReceivedL(TDesC& aData)
00312 //
00313 // a callback to observer indicating that listener has received data
00314 // ----------------------------------------------------------------------------
00315 void CListener::HandleListenerDataReceivedL(const TDesC& aData)
00316     {
00317     iObserver.HandleListenerDataReceivedL(aData);
00318     }
00319 
00320 
00321 // ----------------------------------------------------------------------------
00322 // CListener::HandleListenerConnectedL()
00323 //
00324 // a callback to observer indicating that listener has been connected to
00325 // ----------------------------------------------------------------------------
00326 void CListener::HandleListenerConnectedL()
00327     {
00328     iIsConnected=ETrue;
00329     iObserver.HandleListenerConnectedL();
00330     }
00331 
00332 
00333 // ----------------------------------------------------------------------------
00334 // CListener::HandleListenerDisconnectedL()
00335 //
00336 // a callback to observer indicating that listener has been disconnected
00337 // ----------------------------------------------------------------------------
00338 void CListener::HandleListenerDisconnectedL()
00339     {
00340     iIsConnected=EFalse;
00341     iObserver.HandleListenerDisconnectedL();
00342     }
00343 

Generated by  doxygen 1.6.2