examples/ForumNokia/BluetoothPMPExample/src/Listener.cpp

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

Generated by  doxygen 1.6.2