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