localconnectivityservice/obexserviceman/obexservicemanserver/src/SrcsSession.cpp
branchRCL_3
changeset 40 52a167391590
parent 0 c3e98f10fcf4
equal deleted inserted replaced
39:4096754ee773 40:52a167391590
       
     1 /*
       
     2 * Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  SRCS session handler. Dispatchs requests from
       
    15 *                clients and serves them.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 
       
    23 #include "SrcsSession.h"
       
    24 #include "obexsm.h"
       
    25 #include "SrcsMessage.h"
       
    26 #include "debug.h"
       
    27 #include <btfeaturescfg.h>
       
    28 
       
    29 
       
    30 // CONSTANTS
       
    31 
       
    32 // The granularity of the array used to hold CSrcsMessage objects
       
    33 static const TInt KMessageArrayGranularity = 4;
       
    34 
       
    35 
       
    36 
       
    37 // ================= MEMBER FUNCTIONS =======================
       
    38 
       
    39 // ---------------------------------------------------------
       
    40 // C++ default constructor can NOT contain any code, that
       
    41 // might leave.
       
    42 // constructor - must pass client to CSession2
       
    43 // ---------------------------------------------------------
       
    44 //
       
    45 CSrcsSession::CSrcsSession(CObexSM* aServer) : CSession2(),
       
    46                                             iServer(aServer),
       
    47                                             iCanceling(EFalse)
       
    48     {
       
    49     if(iServer)
       
    50         {    
       
    51         iServer->IncSessionCount();
       
    52         }
       
    53     }
       
    54 // ---------------------------------------------------------
       
    55 // destructor
       
    56 // ---------------------------------------------------------
       
    57 //
       
    58 CSrcsSession::~CSrcsSession()
       
    59     {
       
    60     FLOG(_L("[SRCS]\tserver\tCSrcsSession closed."));
       
    61     if ( iMessageArray )
       
    62         {
       
    63         // Cleanup the array
       
    64         iMessageArray->ResetAndDestroy();
       
    65         }
       
    66     delete iMessageArray;
       
    67     if(iServer)
       
    68         {    
       
    69         iServer->DecSessionCount();
       
    70         } 
       
    71     }
       
    72 // ---------------------------------------------------------
       
    73 // Two-phased constructor.
       
    74 // ---------------------------------------------------------
       
    75 //
       
    76 CSrcsSession* CSrcsSession::NewL(CObexSM* aServer)
       
    77     {
       
    78     return new(ELeave) CSrcsSession(aServer);
       
    79     }
       
    80 
       
    81 // ---------------------------------------------------------
       
    82 // Server
       
    83 // Return a reference to CSrcs
       
    84 // ---------------------------------------------------------
       
    85 CObexSM& CSrcsSession::Server()
       
    86     {
       
    87     return *iServer;
       
    88     }
       
    89 
       
    90 // ---------------------------------------------------------
       
    91 // CreateL
       
    92 // 2nd phase construct for sessions
       
    93 // - called by the CServer framework
       
    94 // ---------------------------------------------------------
       
    95 void CSrcsSession::CreateL()
       
    96     {
       
    97     // Add session to server first.
       
    98     // If anything leaves, it will be removed by the destructor
       
    99     ConstructL();
       
   100     }
       
   101 
       
   102 // ---------------------------------------------------------
       
   103 // ConstructL
       
   104 // 2nd phase construct for sessions
       
   105 // - called by the CServer framework
       
   106 //
       
   107 // ---------------------------------------------------------
       
   108 void CSrcsSession::ConstructL()
       
   109     {
       
   110     iMessageArray = new(ELeave) CArrayPtrFlat<CSrcsMessage>(KMessageArrayGranularity);
       
   111     }
       
   112 
       
   113 // ---------------------------------------------------------
       
   114 // HandleError
       
   115 // Handle an error from ServiceL()
       
   116 // A bad descriptor error implies a badly programmed client, so panic it;
       
   117 // otherwise report the error to the client
       
   118 //
       
   119 // ---------------------------------------------------------
       
   120 void CSrcsSession::HandleError(TInt aError, const RMessage2& aMessage)
       
   121     {
       
   122     FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession::HandleError(): %d"), aError));
       
   123     if (aError==KErrBadDescriptor)
       
   124         {
       
   125         PanicClient( aMessage, ESrcsBadDescriptor);
       
   126         }
       
   127     else
       
   128         {
       
   129         CompleteMessage( aMessage, aError);
       
   130         }
       
   131     }
       
   132 
       
   133 
       
   134 // ---------------------------------------------------------
       
   135 // ServiceL
       
   136 // Calls DispatchMessage under trap harness
       
   137 //
       
   138 // ---------------------------------------------------------
       
   139 void CSrcsSession::ServiceL(const RMessage2& aMessage)
       
   140     {
       
   141     // First make our own message from RMessage2
       
   142     // TRAP because message needs to be completed
       
   143     // in case of Leave.        
       
   144     TRAPD( err, CreateSrcsMessageL( aMessage ));
       
   145     if ( err )
       
   146         {
       
   147         FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession: ServiceL. Error %d when creating message."), err));
       
   148         aMessage.Complete( err );
       
   149         }
       
   150     else
       
   151         {
       
   152         err = KErrNone;
       
   153         TRAP( err ,DispatchMessageL( aMessage ));
       
   154 
       
   155         // If we have an error, try to handle it with handle-error.
       
   156         if ( err )
       
   157             {
       
   158             HandleError( err, aMessage );
       
   159             }
       
   160         }
       
   161     }
       
   162 
       
   163 // ---------------------------------------------------------
       
   164 // CreateSrcsMessageL
       
   165 // Creates a CSrcsMessage and appends it to iMessageArray.
       
   166 // ---------------------------------------------------------
       
   167 //
       
   168 void CSrcsSession::CreateSrcsMessageL(const RMessage2& aMessage)
       
   169     {
       
   170     __ASSERT_DEBUG(iMessageArray!=NULL, PanicServer(ESrcsClassMemberVariableIsNull));
       
   171     CSrcsMessage* message = CSrcsMessage::NewL(aMessage);
       
   172     CleanupStack::PushL( message );
       
   173     iMessageArray->AppendL( message );
       
   174     CleanupStack::Pop();
       
   175     FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession: MessageArray count: %d"), iMessageArray->Count()));
       
   176     }
       
   177 
       
   178 // ---------------------------------------------------------
       
   179 // CompleteMessage
       
   180 // Finds a message based on aMessage and completes it.
       
   181 // ---------------------------------------------------------
       
   182 //
       
   183 void CSrcsSession::CompleteMessage(const RMessage2& aMessage, TInt aReason)
       
   184     {
       
   185     FLOG(_L("[SRCS]\tserver\tCSrcsSession: CompleteMessage."));
       
   186     CSrcsMessage* message = FindMessage(aMessage);
       
   187     __ASSERT_DEBUG(message!=NULL, PanicServer(ESrcsBadMessage));
       
   188     message->Complete(aReason);
       
   189     DeleteMessage( message );
       
   190     }
       
   191 
       
   192 // ---------------------------------------------------------
       
   193 // CompleteMessage
       
   194 // Completes given message.
       
   195 // ---------------------------------------------------------
       
   196 //
       
   197 void CSrcsSession::CompleteMessage(CSrcsMessage* aMessage, TInt aReason)
       
   198     {
       
   199     __ASSERT_DEBUG(aMessage!=NULL, PanicServer(ESrcsBadMessage));
       
   200     FLOG(_L("[SRCS]\tserver\tCSrcsSession: CompleteMessage."));
       
   201     aMessage->Complete(aReason);
       
   202     DeleteMessage(aMessage);
       
   203     }
       
   204 
       
   205 // ---------------------------------------------------------
       
   206 // CompletePendingMessages
       
   207 // Completes any messages pending in the CBTManMessage array.
       
   208 // ---------------------------------------------------------
       
   209 void CSrcsSession::CompletePendingMessages()
       
   210     {
       
   211     __ASSERT_DEBUG(iMessageArray!=NULL, PanicServer(ESrcsClassMemberVariableIsNull));
       
   212     CSrcsMessage* messagePtr = NULL;
       
   213     TInt count = iMessageArray->Count();
       
   214     FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession::CompletePendingMessages. Message count: %d"), count));
       
   215 
       
   216     // Messages can be completed from array
       
   217     // and deleted after that.
       
   218     for ( TInt index = ( count-1 ) ; index >= 0 ; index-- )
       
   219         {
       
   220         messagePtr = iMessageArray->At(index);
       
   221         messagePtr->Complete(KErrDied);
       
   222         iMessageArray->Delete(index);
       
   223         delete messagePtr;
       
   224         messagePtr = NULL;
       
   225         }
       
   226     }
       
   227 
       
   228 // ---------------------------------------------------------
       
   229 // FindMessage
       
   230 // Searches the array of CBTManMessages for the one dealing with aMessage.
       
   231 // ---------------------------------------------------------
       
   232 //
       
   233 CSrcsMessage* CSrcsSession::FindMessage(const RMessage2& aMessage)
       
   234     {
       
   235     __ASSERT_DEBUG(iMessageArray!=NULL, PanicServer(ESrcsClassMemberVariableIsNull));
       
   236     FLOG(_L("[SRCS]\tserver\tCSrcsSession: FindMessage."));
       
   237     RMessagePtr2 messagePtr = aMessage;
       
   238     CSrcsMessage* ptr = NULL;
       
   239 
       
   240     for ( TInt index = 0 ; index < iMessageArray->Count() ; index++ )
       
   241         {
       
   242         ptr = iMessageArray->At( index );
       
   243         if( ptr->MessagePtr() == messagePtr )
       
   244             {
       
   245             FLOG(_L("[SRCS]\tserver\tCSrcsSession: FindMessage. Message found"));
       
   246             return ptr;
       
   247             }
       
   248         }
       
   249     return NULL;
       
   250     }
       
   251 
       
   252 // ---------------------------------------------------------
       
   253 // FindMessage
       
   254 // Searches the array for the 1st message with the function.
       
   255 // ---------------------------------------------------------
       
   256 //
       
   257 CSrcsMessage* CSrcsSession::FindMessage(TInt aFunction)
       
   258     {
       
   259     __ASSERT_DEBUG(iMessageArray!=NULL, PanicServer(ESrcsClassMemberVariableIsNull));
       
   260     FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession: FindMessage aFunction %d"), aFunction));
       
   261     CSrcsMessage* ptr = NULL;
       
   262     for ( TInt index = 0 ; index < iMessageArray->Count() ; index++ )
       
   263         {
       
   264         ptr = iMessageArray->At( index );
       
   265         if ( ptr->MessagePtr().Function() == aFunction )
       
   266             {
       
   267             FLOG(_L("[SRCS]\tserver\tCSrcsSession: FindMessage. Message found"));
       
   268             return ptr;
       
   269             }
       
   270         }
       
   271     FLOG(_L("[SRCS]\tserver\tCSrcsSession: FindMessage. Message not found"));
       
   272     return NULL;
       
   273     }
       
   274 
       
   275 // ---------------------------------------------------------
       
   276 // DeleteMessage
       
   277 // Find the CSrcsMessage in the message array and delete it.
       
   278 // ---------------------------------------------------------
       
   279 //
       
   280 void CSrcsSession::DeleteMessage(CSrcsMessage* aMessage)
       
   281     {
       
   282     __ASSERT_DEBUG(iMessageArray!=NULL, PanicServer(ESrcsClassMemberVariableIsNull));
       
   283     FLOG(_L("[SRCS]\tserver\tCSrcsSession: DeleteMessage. "));
       
   284     CSrcsMessage* ptr = NULL;
       
   285     TInt count = iMessageArray->Count();
       
   286     for ( TInt index = ( count-1 ) ; index >= 0 ; index-- )
       
   287         {
       
   288         ptr = iMessageArray->At( index );
       
   289         if( ptr == aMessage )
       
   290             {
       
   291             FLOG(_L("[SRCS]\tserver\tCSrcsSession: Message deleting. "));
       
   292             //Delete the message first before removing from the array since a helper associated
       
   293             //with the message will try to find the message by parsing the array as part of the
       
   294             //destruction the message.
       
   295             delete ptr;
       
   296             iMessageArray->Delete( index );
       
   297             ptr = NULL;
       
   298             break;
       
   299             }
       
   300         }
       
   301     FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession: MessageArray count: %d"), iMessageArray->Count()));
       
   302     //compress the array if the count is less than the length - granularity AND if the count != 0
       
   303     if ( iMessageArray->Count() )
       
   304         {
       
   305         if (iMessageArray->Length() - iMessageArray->Count() >= KMessageArrayGranularity)
       
   306             iMessageArray->Compress();
       
   307         }
       
   308     }
       
   309 
       
   310 
       
   311 // ---------------------------------------------------------
       
   312 // DispatchMessageL
       
   313 // service a client request; test the opcode and then do
       
   314 // appropriate servicing
       
   315 // ---------------------------------------------------------
       
   316 //
       
   317 void CSrcsSession::DispatchMessageL(const RMessage2 &aMessage)
       
   318     {
       
   319     FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession: DispatchMessageL function %d"), aMessage.Function()));
       
   320     iCanceling=EFalse;
       
   321     switch (aMessage.Function())
       
   322         {
       
   323         // Turn BT services ON (with service handler).
       
   324     case ESrcsBTServicesON:
       
   325             {
       
   326 			if ( BluetoothFeatures::EnterpriseEnablementL() != BluetoothFeatures::EEnabled )
       
   327 				{
       
   328 				CompleteMessage(aMessage, KErrNotSupported);
       
   329 				}
       
   330 			else
       
   331 				{			
       
   332 	            ManageServices(ESrcsTransportBT, ETrue, aMessage);
       
   333 				}
       
   334             break;
       
   335             }
       
   336         // Turn BT services OFF.
       
   337     case ESrcsBTServicesOFF:
       
   338             {
       
   339             ManageServices(ESrcsTransportBT, EFalse, aMessage);
       
   340             break;
       
   341             }
       
   342 
       
   343         // Turn IrDA services ON (with service handler).
       
   344     case ESrcsIrDAServicesON:
       
   345             {
       
   346             ManageServices(ESrcsTransportIrDA, ETrue, aMessage);
       
   347             break;
       
   348             }
       
   349         // Turn IrDA services OFF.
       
   350     case ESrcsIrDAServicesOFF:
       
   351             {
       
   352             ManageServices(ESrcsTransportIrDA, EFalse, aMessage);
       
   353             break;
       
   354             }
       
   355 
       
   356     case ESrcsStartUSB:
       
   357             {
       
   358             ManageServices(ESrcsTransportUSB, ETrue, aMessage);
       
   359             break;
       
   360             }
       
   361     case ESrcsStopUSB:
       
   362             {
       
   363             ManageServices(ESrcsTransportUSB, EFalse, aMessage);
       
   364             break;
       
   365             }    
       
   366      case ESrcsCancelRequest:
       
   367             {            
       
   368             FLOG(_L("[SRCS]\tserver\tCSrcsSession: DispatchMessageL: ESrcsCancelRequest"));
       
   369             CancelingRequest(aMessage);
       
   370             break;
       
   371             }
       
   372     default:
       
   373             {
       
   374             PanicClient( aMessage, ESrcsBadRequest);
       
   375             break;
       
   376             }
       
   377         }
       
   378     }
       
   379 
       
   380 // ---------------------------------------------------------
       
   381 // ManageServicesL
       
   382 // OpCode function; Manages Services.
       
   383 // ---------------------------------------------------------
       
   384 //
       
   385 void CSrcsSession::ManageServices(TSrcsTransport aTransport, TBool aState, 
       
   386                                   const RMessage2& aMessage)
       
   387     {
       
   388     FLOG(_L("[SRCS]\tserver\tCSrcsSession: ManageServicesL"));
       
   389     TInt retVal = Server().ManageServices(aTransport, aState, this, aMessage);
       
   390     FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession: ManageServicesL return %d"), retVal));
       
   391     }
       
   392 
       
   393 // ---------------------------------------------------------
       
   394 // CancelingRequest
       
   395 // Canceling the ongoing request.
       
   396 // ---------------------------------------------------------
       
   397 //
       
   398 void CSrcsSession::CancelingRequest(const RMessage2& aMessage)
       
   399     {
       
   400     FLOG(_L("[SRCS]\tserver\tCSrcsSession: CancelingRequest"));
       
   401     iCanceling=ETrue;          
       
   402     if (iMessageArray->Count() == 1)
       
   403         {
       
   404         FLOG(_L("[SRCS]\tserver\tCSrcsSession: CancelingRequest completing"));
       
   405         CompleteMessage(aMessage, KErrGeneral);        
       
   406         }
       
   407     else
       
   408         {
       
   409         //The cancel handling continues, when another request completes.
       
   410         }
       
   411     }
       
   412     
       
   413 // ---------------------------------------------------------
       
   414 // RequestCompleted
       
   415 // ---------------------------------------------------------
       
   416 //   
       
   417 void CSrcsSession::RequestCompleted(const RMessage2 &aMessage, TInt aError)
       
   418     {          
       
   419     FLOG(_L("[SRCS]\tserver\tCSrcsSession: RequestCompleted"));
       
   420     TBool postponeCompletion = EFalse;
       
   421     if ( !iCanceling )
       
   422         {
       
   423         FLOG(_L("[SRCS]\tserver\tCSrcsSession: RequestCompleted completing"));
       
   424         CompleteMessage( aMessage, aError ); 
       
   425         }
       
   426     else
       
   427         {
       
   428         CompleteCanceling(aMessage, aError, postponeCompletion);
       
   429         }
       
   430     if ( !postponeCompletion && iMessageArray->Count() > 0 )
       
   431         {
       
   432         FLOG(_L("[SRCS]\tserver\tCSrcsSession: RequestCompleted dispatching"));
       
   433         CSrcsMessage* messagePtr = NULL; 
       
   434         messagePtr=iMessageArray->At( 0 ); 
       
   435         RMessage2 message=messagePtr->MessagePtr(); 
       
   436         TRAP_IGNORE( DispatchMessageL( message ) );
       
   437         }    
       
   438     FLOG(_L("[SRCS]\tserver\tCSrcsSession: RequestCompleted exit"));
       
   439     }
       
   440 
       
   441 // ---------------------------------------------------------
       
   442 // CompleteCanceling
       
   443 // Only USB service cancel is handled, since Locod Service 
       
   444 // Plugin API does not allow cancel for BT or IrDA.
       
   445 // ---------------------------------------------------------
       
   446 //
       
   447 void CSrcsSession::CompleteCanceling(const RMessage2& aMessage, TInt aError, 
       
   448                                      TBool& aPostponeCompletion)
       
   449     {          
       
   450     FLOG(_L("[SRCS]\tserver\tCSrcsSession: CompleteCanceling"));
       
   451     TBool cancelMsgFound = EFalse;
       
   452     CSrcsMessage* messagePtr = NULL;
       
   453     FTRACE(FPrint(_L("[SRCS]\tserver\tCSrcsSession: CompleteCanceling function %d"), 
       
   454         aMessage.Function()));
       
   455     switch ( aMessage.Function() )
       
   456         {    
       
   457         case ESrcsStartUSB:
       
   458             messagePtr = FindMessage(ESrcsCancelRequest);
       
   459             if ( messagePtr )
       
   460                 {
       
   461                 FLOG(_L("[SRCS]\tserver\tCSrcsSession: CompleteCanceling ESrcsStartUSB found cancel req"));
       
   462                 RMessage2 message=messagePtr->MessagePtr();                
       
   463                 ManageServices(ESrcsTransportUSB, EFalse,  message);
       
   464                 aPostponeCompletion = ETrue;
       
   465                 cancelMsgFound = ETrue;
       
   466                 }
       
   467             break;
       
   468         case ESrcsStopUSB:
       
   469             messagePtr = FindMessage(ESrcsCancelRequest);
       
   470             if ( messagePtr )
       
   471                 {
       
   472                 CompleteMessage(aMessage, KErrCancel); 
       
   473                 CompleteMessage(messagePtr, aError); 
       
   474                 cancelMsgFound = ETrue;
       
   475                 }
       
   476             break;
       
   477         case ESrcsCancelRequest:
       
   478             //either start or stop USB
       
   479             messagePtr = FindMessage(ESrcsStartUSB);
       
   480             if ( !messagePtr )
       
   481                 {
       
   482                 messagePtr = FindMessage(ESrcsStopUSB);
       
   483                 }
       
   484             if ( messagePtr )
       
   485                 {
       
   486                 CompleteMessage(messagePtr, KErrCancel); 
       
   487                 CompleteMessage(aMessage, aError);
       
   488                 cancelMsgFound = ETrue;
       
   489                 }
       
   490             break;
       
   491         default:
       
   492             FLOG(_L("[SRCS]\tserver\tCSrcsSession: CompleteCanceling ESrcsCancelRequest unhandled msg"));
       
   493             break;
       
   494         }
       
   495     if ( !cancelMsgFound )
       
   496         {
       
   497         FLOG(_L("[SRCS]\tserver\tCSrcsSession: CompleteCanceling no message"));
       
   498         CompleteMessage(aMessage, KErrGeneral);
       
   499         }
       
   500     FLOG(_L("[SRCS]\tserver\tCSrcsSession: CompleteCanceling exit"));    
       
   501     }
       
   502 // End of File