00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "serversession.h"
00026 #include "concreteconnection.h"
00027 #include "Log.h"
00028 #include "bt_sock.h"
00029
00030
00031 CServerSession::CServerSession(RThread& aClient,
00032 CCobainServer* aServer)
00033 : CSession(aClient),
00034 iServer(aServer)
00035 {
00036 Log::Print(_L("** created a session"));
00037
00038
00039 Mem::FillZ(iConnections, sizeof(iConnections));
00040 }
00041
00042 CServerSession::~CServerSession()
00043 {
00044
00045
00046 Log::Print(_L("** Session dying"));
00047
00048
00049 iBTCommunicator->StopListeningL();
00050 delete iBTCommunicator;
00051 iBTCommunicator = NULL;
00052
00053
00054 for( TInt i = 0; i < KMaxSocketCount; i++ ) {
00055 if( iConnections[i] != NULL ) {
00056 Log::Print(_L("~CServerSession: killing con %d"), i);
00057
00058 iConnections[i]->Close(ETrue);
00059
00060 delete iConnections[i];
00061 iConnections[i] = NULL;
00062 }
00063 }
00064
00065
00066 iServer->DecrementSession();
00067
00068
00069 if( iPeerList != NULL ) {
00070 iPeerList->ResetAndDestroy();
00071 delete iPeerList;
00072 iPeerList = NULL;
00073 }
00074 }
00075
00076 CServerSession* CServerSession::NewL(RThread& aClient,
00077 CCobainServer* aServer)
00078 {
00079 CServerSession *session = new (ELeave)CServerSession(aClient, aServer);
00080 CleanupStack::PushL(session);
00081 session->ConstructL();
00082 CleanupStack::Pop();
00083
00084 return session;
00085 }
00086
00087 void CServerSession::ConstructL()
00088 {
00089
00090 iServer->IncrementSession();
00091
00092
00093 iBTCommunicator = CBTCommunicator::NewL(this);
00094 }
00095
00096 CConcreteConnection* CServerSession::GetConnection(TInt id)
00097 {
00098 if( (id < 0) || (id >= KMaxSocketCount) ) {
00099 User::Panic(KSessionPanic, KErrSessionBadSocketTableIndex);
00100 }
00101
00102 CConcreteConnection *con = iConnections[id];
00103 if( con == NULL ) {
00104 User::Panic(KSessionPanic, KErrSessionConnectionNotFoundInGet);
00105 }
00106
00107 return con;
00108 }
00109
00110
00111 TInt CServerSession::AllocateConnection(CConcreteConnection *aConnection)
00112 {
00113 TInt slot = -1;
00114
00115 __ASSERT_ALWAYS(!aConnection->IsListening(),
00116 User::Panic(KSessionPanic, KErrSessionTryingToAllocListeningCon));
00117
00118 for( TInt i = 0; i < KMaxSocketCount; i++ ) {
00119 if( iConnections[i] == NULL ) {
00120 slot = i;
00121 break;
00122 }
00123 }
00124
00125 if( slot == -1 ) {
00126
00127 CCobainServer::PanicServer(CCobainServer::ESocketTableFull);
00128 }
00129
00130 Log::Print(_L("AllocateConnection(): id: %d"), slot);
00131
00132 iConnections[slot] = aConnection;
00133
00134 return slot;
00135 }
00136
00137
00138 void CServerSession::DeallocateConnection(CConcreteConnection *aConnection)
00139 {
00140 __ASSERT_ALWAYS(!aConnection->IsListening(),
00141 User::Panic(KSessionPanic, KErrSessionTryingToDeallocListeningCon));
00142
00143 Log::Print(_L("DeallocateConnection()"));
00144
00145 for( TInt i = 0; i < KMaxSocketCount; i++ ) {
00146 if( aConnection == iConnections[i] ) {
00147 iConnections[i] = NULL;
00148 return;
00149 }
00150 }
00151
00152 Log::Print(_L("DeallocateConnection() exiting.."));
00153 }
00154
00155 void CServerSession::SetPeerList(TPeerDataList *aPeerList)
00156 {
00157
00158 delete iPeerList;
00159 iPeerList = aPeerList;
00160 }
00161
00162
00163
00164
00165 void CServerSession::GetPeer(const RMessage &aMessage)
00166 {
00167 TInt n = aMessage.Int0();
00168
00169 Log::Print(_L("CServerSession::GetPeer(): n: %d"), n);
00170
00171 if( (n < 0) || (n >= iPeerList->Count()) ) {
00172
00173 aMessage.Complete(KErrArgument);
00174 }
00175
00176
00177 TPeerData *data = (*iPeerList)[n];
00178 TPeerDataBuf buf = *data;
00179 aMessage.WriteL(aMessage.Ptr1(), buf);
00180
00181 aMessage.Complete(KErrNone);
00182 return;
00183 }
00184
00185
00186
00187
00188 void CServerSession::GetNumPeersL(const RMessage &aMessage)
00189 {
00190
00191 if( iPeerList != NULL ) {
00192 iPeerList->ResetAndDestroy();
00193 delete iPeerList;
00194 iPeerList = NULL;
00195 }
00196
00197 switch( aMessage.Int0() ) {
00198 case EBluetooth:
00199
00200
00201 iBTCommunicator->DiscoverPeersL(aMessage,
00202 *this);
00203 break;
00204 default:
00205 PanicClient(aMessage, CCobainServer::EBadRequest);
00206 break;
00207 }
00208 }
00209
00210
00211
00212
00213
00214
00215 void CServerSession::ConnectL(const RMessage &aMessage)
00216 {
00217 TPeerDataBuf buf;
00218 TInt err = KErrNone;
00219
00220
00221 aMessage.ReadL(aMessage.Ptr1(), buf);
00222 TPeerData &data = buf();
00223
00224
00225 RSocket *socket = NULL;
00226 TInt mtu = 0;
00227
00228 switch ( aMessage.Int0() ) {
00229 case EBluetooth:
00230 TRAP(err, (socket = iBTCommunicator->ConnectL(&data)));
00231 mtu = CBTCommunicator::ResolveMTU(*socket);
00232 break;
00233
00234 default:
00235 PanicClient(aMessage, CCobainServer::EUnsupportedProtocol);
00236 break;
00237 }
00238
00239 if( err != KErrNone ) {
00240 Log::Print(_L("ConnectL() error: %d"), err);
00241
00242
00243 aMessage.Complete(err);
00244 return;
00245 }
00246
00247
00248 TInt slot = AllocateConnection(CConcreteConnection::NewL(socket, *this, mtu));
00249
00250
00251 TPckgBuf<TInt> id_buf(slot);
00252 aMessage.WriteL(aMessage.Ptr2(), id_buf);
00253
00254 aMessage.Complete(KErrNone);
00255
00256 Log::Print(_L("CServerSession::ConnectL() returning.."));
00257 }
00258
00259
00260
00261 void CServerSession::CloseSocket(const RMessage &aMessage)
00262 {
00263 TInt n = aMessage.Int0();
00264
00265 Log::Print(_L("CServerSession::CloseSocket() %d"), n);
00266
00267 CConcreteConnection *con = GetConnection(n);
00268 DeallocateConnection(con);
00269
00270 TBool immediately = (TBool)aMessage.Int1();
00271
00272 Log::Print(_L("calling con->Close()"));
00273
00274 con->Close(immediately);
00275 delete con;
00276
00277 aMessage.Complete(KErrNone);
00278
00279 Log::Print(_L("CloseSocket() exiting"));
00280 }
00281
00282
00283
00284
00285 void CServerSession::GetIncomingConnection(const RMessage& aMessage)
00286 {
00287 if( iListeningConnection == NULL ) {
00288 PanicClient(aMessage, CCobainServer::ENotListening);
00289 }
00290
00291
00292 iListeningConnection->ListenL(aMessage);
00293 }
00294
00295
00296
00297
00298
00299
00300 void CServerSession::StartListen(const RMessage& aMessage)
00301 {
00302 if( iListeningConnection != NULL ) {
00303 PanicClient(aMessage, CCobainServer::EAlreadyListening);
00304 }
00305
00306 TUint port = (TUint)aMessage.Int1();
00307 TUint list_sock_type = (TUint)aMessage.Int2();
00308
00309
00310 _LIT8(KServiceName, "Cobain");
00311 _LIT8(KServiceDesc, "CobainServiceDesc");
00312
00313 switch( aMessage.Int0() ) {
00314 case EBluetooth:
00315 iListeningConnection = iBTCommunicator->StartListeningL(port,
00316 -1,
00317 KServiceName,
00318 KServiceDesc,
00319 list_sock_type);
00320 break;
00321 default:
00322 PanicClient(aMessage, CCobainServer::EUnsupportedProtocol);
00323 break;
00324 }
00325
00326
00327 aMessage.Complete(KErrNone);
00328 }
00329
00330
00331 void CServerSession::AbortListen(const RMessage& aMessage)
00332 {
00333 Log::Print(_L("AbortListen()"));
00334
00335 switch( aMessage.Int0() ) {
00336 case EBluetooth:
00337 iBTCommunicator->StopListeningL();
00338 break;
00339 default:
00340 PanicClient(aMessage, CCobainServer::EUnsupportedProtocol);
00341 break;
00342 }
00343
00344 iListeningConnection = NULL;
00345
00346 aMessage.Complete(KErrNone);
00347 }
00348
00349
00350
00351 void CServerSession::Receive(const RMessage& aMessage)
00352 {
00353 Log::Print(_L("CServerSession::Receive()"));
00354
00355 TInt n = aMessage.Int0();
00356 CConcreteConnection *con = GetConnection(n);
00357 con->ReceiveL(aMessage);
00358
00359 Log::Print(_L("CServerSession::Receive() returning"));
00360 }
00361
00362
00363 void CServerSession::CancelReceive(const RMessage &aMessage)
00364 {
00365 Log::Print(_L("CancelReceive()"));
00366
00367 TInt id = aMessage.Int0();
00368 CConcreteConnection *con = GetConnection(id);
00369 con->CancelReceive();
00370 aMessage.Complete(KErrNone);
00371 }
00372
00373
00374
00375
00376 void CServerSession::Send(const RMessage &aMessage)
00377 {
00378 TInt id = aMessage.Int0();
00379 TInt len = aMessage.Int1();
00380
00381 Log::Print(_L("Send(): id: %d, len: %d"), id, len);
00382
00383
00384
00385 HBufC8 *buf = HBufC8::NewL(len);
00386 CleanupStack::PushL(buf);
00387
00388
00389 TPtr8 ptr = buf->Des();
00390 aMessage.ReadL(aMessage.Ptr2(), ptr);
00391
00392
00393 CConcreteConnection *con = GetConnection(id);
00394
00395
00396 TRAPD(err, con->SendL(buf));
00397
00398 CleanupStack::Pop();
00399
00400
00401
00402 aMessage.Complete(err);
00403 }
00404
00405 void CServerSession::ServiceL(const RMessage& aMessage)
00406 {
00407 TInt function = aMessage.Function();
00408
00409
00410
00411 switch( function )
00412 {
00413 case CCobainServer::ESend:
00414 Send(aMessage);
00415 break;
00416 case CCobainServer::EConnect:
00417 ConnectL(aMessage);
00418 break;
00419 case CCobainServer::ECloseSocket:
00420 CloseSocket(aMessage);
00421 break;
00422 case CCobainServer::EGetNumPeers:
00423 GetNumPeersL(aMessage);
00424 break;
00425 case CCobainServer::EGetPeer:
00426 GetPeer(aMessage);
00427 break;
00428 case CCobainServer::EStartListen:
00429 StartListen(aMessage);
00430 break;
00431 case CCobainServer::EAbortListen:
00432 AbortListen(aMessage);
00433 break;
00434 case CCobainServer::EGetIncomingConnection:
00435 GetIncomingConnection(aMessage);
00436 break;
00437 case CCobainServer::EReceive:
00438 Receive(aMessage);
00439 break;
00440 case CCobainServer::ECancelReceive:
00441 CancelReceive(aMessage);
00442 break;
00443 default:
00444 PanicClient(aMessage, CCobainServer::EBadRequest);
00445 break;
00446 }
00447
00448
00449 }
00450
00451 void CServerSession::PanicClient(const RMessage& aMessage,
00452 CCobainServer::TServerPanic aPanic)
00453 {
00454 aMessage.Panic(KClientPanic, aPanic);
00455 }