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