examples/Qt/qtbluetoothapp/listener.cpp

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

Generated by  doxygen 1.6.2