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
1.6.2