hti/HtiCommPlugins/HtiBtCommPlugin/HtiBtCommServer/src/HtiBtCommServerSession.cpp
branchRCL_3
changeset 59 8ad140f3dd41
equal deleted inserted replaced
49:7fdc9a71d314 59:8ad140f3dd41
       
     1 /*
       
     2 * Copyright (c) 2009 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:  Implementation of CHtiBtCommServerSession class. This class
       
    15 *                represents the client session in server.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include "HtiBtClientServerCommon.h"
       
    23 #include "HtiBtCommServerSession.h"
       
    24 #include "HtiBtCommServer.h"
       
    25 #include "BtSerialClient.h"
       
    26 #include "Logger.h"
       
    27 
       
    28 #include <e32base.h>
       
    29 #include <e32std.h>
       
    30 #include <e32svr.h>
       
    31 
       
    32 #include <HtiCommPluginInterface.h> // KErrComModuleReset;
       
    33 
       
    34 // CONSTANTS
       
    35  _LIT(KBtComSessPanic, "BtComSessAssrt");
       
    36 
       
    37 const TInt KBtAddressHexStringLength = 12; // 6 bytes
       
    38 const TInt KIncomingDataBufSize = 32 * 1024;
       
    39 
       
    40 //*****************************************************************************
       
    41 //
       
    42 // Class CHtiBtCommServerSession
       
    43 //
       
    44 //*****************************************************************************
       
    45 
       
    46 /*---------------------------------------------------------------------------*/
       
    47 CHtiBtCommServerSession::CHtiBtCommServerSession( CHtiBtCommServer* aServer )
       
    48     : CSession2()
       
    49     {
       
    50     LOGFW(DebugLog(_L("CHtiBtCommServerSession: CHtiBtCommServerSession()")))
       
    51 
       
    52     __DECLARE_NAME( _S( "CHtiBtCommServerSession" ) );
       
    53     iBtCommServer = aServer;
       
    54     iReadRequestComplete = ETrue;  // ready to accept read request
       
    55     iWriteRequestComplete = ETrue;
       
    56     iConnectRequestComplete = ETrue;
       
    57     iBtCommServer->SessionCreated(this);
       
    58     }
       
    59 
       
    60 /*---------------------------------------------------------------------------*/
       
    61 CHtiBtCommServerSession* CHtiBtCommServerSession::NewL(
       
    62     CHtiBtCommServer* aServer )
       
    63     {
       
    64     LOGFW(DebugLog(_L("CHtiBtCommServerSession: NewL()")))
       
    65     CHtiBtCommServerSession* session =
       
    66         new (ELeave) CHtiBtCommServerSession( aServer );
       
    67     CleanupStack::PushL( session );
       
    68     session->ConstructL();
       
    69     CleanupStack::Pop( session );
       
    70     return session;
       
    71     }
       
    72 
       
    73 /*---------------------------------------------------------------------------*/
       
    74 
       
    75 void CHtiBtCommServerSession::ConstructL()
       
    76     {
       
    77     LOGFW(DebugLog(_L("CHtiBtCommServerSession: ConstructL()")))
       
    78     iBtClient = CBtSerialClient::NewL(*this);
       
    79     iIncomingDataBuf = HBufC8::NewL(KIncomingDataBufSize);
       
    80     LOGFW(DebugLog(_L("CHtiBtCommServerSession: ConstructL(): Done")))
       
    81     }
       
    82 
       
    83 /*---------------------------------------------------------------------------*/
       
    84 CHtiBtCommServerSession::~CHtiBtCommServerSession()
       
    85     {
       
    86     LOGFW(DebugLog(_L("CHtiBtCommServerSession: ~CHtiBtCommServerSession()")))
       
    87     delete iBtClient;
       
    88     ResetAll(KErrCancel);
       
    89     delete iIncomingDataBuf;
       
    90     if ( iBtCommServer )
       
    91         {
       
    92         iBtCommServer->SessionFreed();
       
    93         }
       
    94     LOGFW(DebugLog(_L("CHtiBtCommServerSession: ~CHtiBtCommServerSession(): Done")))
       
    95     }
       
    96 
       
    97 /*---------------------------------------------------------------------------*/
       
    98 void CHtiBtCommServerSession::ServiceL( const RMessage2& aMessage )
       
    99     {
       
   100     LOGFW(DebugLog(_L("CHtiBtCommServerSession: ServiceL()")))
       
   101 
       
   102     TRAPD( error, DispatchMessageL( aMessage ) );
       
   103     if ( error != KErrNone )
       
   104         {
       
   105         LOGFW(DebugLog(_L("CHtiBtCommServerSession::ServiceL error %d"), error);)
       
   106         }
       
   107     LOGFW(DebugLog(_L("CHtiBtCommServerSession: ServiceL(): Done")))
       
   108     }
       
   109 
       
   110 
       
   111 /*---------------------------------------------------------------------------*/
       
   112 void CHtiBtCommServerSession::DispatchMessageL( const RMessage2 &aMessage )
       
   113     {
       
   114     LOGFW( DebugLog( _L( "CHtiBtCommServerSession: DispatchMessageL()" ) ) )
       
   115 
       
   116     switch ( aMessage.Function() )
       
   117         {
       
   118         case EBtCommServerConnect:
       
   119             {
       
   120             HandleConnectRequestL( aMessage );
       
   121             }
       
   122             break;
       
   123 
       
   124         case EBtCommServerSend:
       
   125             {
       
   126             HandleSendRequestL( aMessage );
       
   127             }
       
   128             break;
       
   129         case EBtCommServerRecv:
       
   130             {
       
   131             HandleReadRequestL( aMessage );
       
   132             }
       
   133             break;
       
   134 
       
   135         case ECancelBtCommServerRecv:
       
   136         case ECancelBtCommServerSend:
       
   137             {
       
   138             HandleCancelRequestL( aMessage );
       
   139             }
       
   140             break;
       
   141 
       
   142         case EGetServicePortNumber:
       
   143             {
       
   144             HandlePortNumberRequestL( aMessage );
       
   145             }
       
   146             break;
       
   147 
       
   148         default:
       
   149             {
       
   150             LOGFW(ErrLog(_L("CHtiBtCommServerSession::DispatchMessageL: Unknown request: %d. Panicing Client"), aMessage.Function());)
       
   151             PanicClient( EBadRequest );
       
   152             User::Panic( KBtComSessPanic, 1 );
       
   153             }
       
   154             break;
       
   155         }
       
   156     LOGFW(DebugLog(_L("CHtiBtCommServerSession: DispatchMessageL(): Done")))
       
   157     }
       
   158 
       
   159 /*---------------------------------------------------------------------------*/
       
   160 void CHtiBtCommServerSession::HandleConnectRequestL( const RMessage2& aMessage )
       
   161     {
       
   162     LOGFW(DebugLog(_L("CHtiBtCommServer:HandleConnectRequestL()")))
       
   163     if ( !iConnectRequestComplete )
       
   164         {
       
   165         LOGFW(DebugLog(_L("CHtiBtCommServer:HandleConnectRequestL(): Already connecting")))
       
   166         aMessage.Complete( KErrNotReady );
       
   167         }
       
   168     else
       
   169         {
       
   170         if ( iBtClient->Connected() )
       
   171             {
       
   172             LOGFW(DebugLog(_L("CHtiBtCommServer:HandleConnectRequestL(): Already connected")))
       
   173             aMessage.Complete( KErrNone ); // Already connected. This is not an error?
       
   174             }
       
   175         else
       
   176             {
       
   177             LOGFW(DebugLog(_L("CHtiBtCommServer:HandleConnectRequestL(): Starting to connect to remote host")))
       
   178             iConnectRequest = aMessage;
       
   179             iConnectRequestComplete = EFalse;
       
   180 
       
   181             TInt dataLength = (TUint16)aMessage.GetDesLength( 0 ); //first message slot
       
   182             LOGFW(DebugLog(_L("CHtiBtCommServer:HandleConnectRequestL(): Data length = %d"), dataLength));
       
   183 
       
   184             TInt port = aMessage.Int1();
       
   185             LOGFW(DebugLog(_L("CHtiBtCommServer:HandleConnectRequestL(): Port = %d"), port));
       
   186 
       
   187             if ( dataLength < 1 )
       
   188                 {
       
   189                 LOGFW(DebugLog(_L("CHtiBtCommServer:HandleConnectRequestL(): No address or name - need to ask device")))
       
   190                 iBtClient->ConnectL(); // Request is completed in ConnectedToServer
       
   191                 }
       
   192             else if ( dataLength == KBtAddressHexStringLength )
       
   193                 {
       
   194                 TBuf8<KBtAddressHexStringLength> addressBuf8;
       
   195                 aMessage.ReadL( 0, addressBuf8 );
       
   196                 TBuf<KBtAddressHexStringLength> addressBuf;
       
   197                 addressBuf.Copy( addressBuf8 );
       
   198                 TBTDevAddr address;
       
   199                 TInt result = address.SetReadable( addressBuf );
       
   200                 LOGFW(DebugLog(_L("CHtiBtCommServer:HandleConnectRequestL(): SetReadable result = %d"), result));
       
   201                 if ( result != KBtAddressHexStringLength )
       
   202                     {
       
   203                     LOGFW(DebugLog(_L("CHtiBtCommServer:HandleConnectRequestL(): Not valid address - use it as name")))
       
   204                     iBtClient->ConnectL( addressBuf, port );
       
   205                     }
       
   206                 else
       
   207                     {
       
   208                     LOGFW(DebugLog(_L("CHtiBtCommServer:HandleConnectRequestL(): Valid address - connect")))
       
   209                     iBtClient->ConnectL( address, port );
       
   210                     }
       
   211                 }
       
   212             else
       
   213                 {
       
   214                 LOGFW(DebugLog(_L("CHtiBtCommServer:HandleConnectRequestL(): Using name to connect")))
       
   215                 TBTDeviceName8 deviceName8;
       
   216                 aMessage.ReadL( 0, deviceName8 );
       
   217                 TBTDeviceName deviceName;
       
   218                 deviceName.Copy( deviceName8 );
       
   219                 iBtClient->ConnectL( deviceName, port );
       
   220                 }
       
   221             }
       
   222         }
       
   223     LOGFW(DebugLog(_L("CHtiBtCommServer:HandleConnectRequestL(): Done")))
       
   224     }
       
   225 
       
   226 /*---------------------------------------------------------------------------*/
       
   227 void CHtiBtCommServerSession::HandleReadRequestL( const RMessage2& aMessage )
       
   228     {
       
   229     LOGFW(DebugLog(_L("CHtiBtCommServerSession: HandleReadRequestL()")))
       
   230 
       
   231     if ( !iReadRequestComplete )
       
   232         {
       
   233         LOGFW(WarnLog(_L("CHtiBtCommServerSession: HandleReadRequestL(): Pending request. ret=KErrNotReady")))
       
   234         // Two simultaneous read requests are not allowed.
       
   235         aMessage.Complete(KErrNotReady);
       
   236         return;
       
   237         }
       
   238 
       
   239     // No data in read buffer. Must wait for new data before completing request
       
   240     iReadRequest = aMessage;
       
   241     iReadRequestComplete = EFalse; // Not ready to complete next request
       
   242     TryCompleteReadRequest(); // if there is something in the readbuffer,
       
   243                               // use it for completion.
       
   244 
       
   245     if ( iIncomingDataBuf->Des().Length() == 0 )
       
   246         {
       
   247         // Read some bytes to buffer even before client's request.
       
   248         iBtClient->ReadAsyncL(); // Issue async request to read more data.
       
   249         }
       
   250 
       
   251     LOGFW(DebugLog(_L("CHtiBtCommServerSession: HandleReadRequestL(): Done")))
       
   252     }
       
   253 
       
   254 /*---------------------------------------------------------------------------*/
       
   255 void CHtiBtCommServerSession::HandleSendRequestL( const RMessage2& aMessage )
       
   256     {
       
   257     LOGFW(DebugLog(_L("CHtiBtCommServerSession: HandleSendRequestL()")))
       
   258 
       
   259     TInt dataLength = (TUint16)aMessage.GetDesLength( 0 ); //first message slot
       
   260     LOGFW( InfoLog( _L( "Framework requested to send data: %d bytes" ), dataLength ) )
       
   261     if ( iBtClient->SendBufferMaxSize() < dataLength )
       
   262         {
       
   263         aMessage.Complete(KErrOverflow);
       
   264         LOGFW(ErrLog(_L("CHtiBtCommServerSession: HandleSendRequestL(): client is giving too big data. Cannot handle.")))
       
   265         }
       
   266     else if ( !iWriteRequestComplete )
       
   267         {
       
   268         LOGFW(WarnLog(_L("CHtiBtCommServerSession: HandleSendRequestL(): Pending request. ret=KErrNotReady")))
       
   269         // Already pending send request. Two simultaneous send requests not allowed.
       
   270         aMessage.Complete( KErrNotReady );
       
   271         }
       
   272     else
       
   273         {
       
   274         if ( iBtClient->FreeSpaceInSendBuffer() < dataLength )
       
   275             {
       
   276             LOGFW(DebugLog(_L("CHtiBtCommServerSession: HandleSendRequestL(): Completing send request delayed")))
       
   277             // No space in the iBtClient's send buffer. Copy the data to internal
       
   278             // buffer and wait for iBtClient to send its data out before adding
       
   279             // data to its send buffer.
       
   280             delete iSendBuffer;
       
   281             iSendBuffer = NULL;
       
   282             iSendBuffer = HBufC8::NewL(dataLength);
       
   283             TPtr8 ptr = iSendBuffer->Des();
       
   284             aMessage.ReadL( 0, ptr );
       
   285             iWriteRequestComplete = EFalse;
       
   286             iWriteRequest = aMessage;
       
   287             // Wait for callback call AllBufferedDataSent. Complete request there.
       
   288             }
       
   289         else
       
   290             {
       
   291             LOGFW(DebugLog(_L("CHtiBtCommServerSession: HandleSendRequestL(): Completing send request immediately")))
       
   292             // All data can be sent immediately, because there is enough space in
       
   293             // iBtClient's send buffer.
       
   294             HBufC8* data = HBufC8::NewLC( dataLength );
       
   295             TPtr8 ptr = data->Des();
       
   296             aMessage.ReadL( 0, ptr );
       
   297             iBtClient->SendL( ptr );
       
   298             CleanupStack::PopAndDestroy( data );
       
   299             aMessage.Complete( KErrNone );
       
   300             }
       
   301         }
       
   302     LOGFW(DebugLog(_L("CHtiBtCommServerSession: HandleSendRequestL(): Done")))
       
   303     }
       
   304 
       
   305 /*---------------------------------------------------------------------------*/
       
   306 void CHtiBtCommServerSession::HandleCancelRequestL( const RMessage2& aMessage )
       
   307     {
       
   308     ResetAll( KErrCancel );
       
   309     aMessage.Complete( KErrNone );
       
   310     }
       
   311 
       
   312 /*---------------------------------------------------------------------------*/
       
   313 void CHtiBtCommServerSession::HandlePortNumberRequestL(const RMessage2& aMessage)
       
   314     {
       
   315     TPckgBuf<TInt> p( iBtClient->ServicePort() );
       
   316     TInt err = aMessage.Write( 0, p, 0 );
       
   317     aMessage.Complete( err );
       
   318     }
       
   319 
       
   320 /*---------------------------------------------------------------------------*/
       
   321 
       
   322 void CHtiBtCommServerSession::PanicClient(TInt aPanic) const
       
   323     {
       
   324     LOGFW(DebugLog(_L("CHtiBtCommServerSession: PanicClient(): %d"), aPanic))
       
   325     LOGFW(WarnLog(_L("CHtiBtCommServerSession: PanicClient(): %d. NOT IMPLEMENTED"), aPanic))
       
   326     aPanic = aPanic;
       
   327     // should be done with RMessage2?
       
   328     }
       
   329 
       
   330 /*---------------------------------------------------------------------------*/
       
   331 void CHtiBtCommServerSession::ResetAll(TInt aCompletionCode)
       
   332     {
       
   333     LOGFW(DebugLog(_L("CHtiBtCommServerSession: ResetAll()")))
       
   334     if ( !iWriteRequestComplete )
       
   335         iWriteRequest.Complete( aCompletionCode );
       
   336     if ( !iReadRequestComplete )
       
   337         iReadRequest.Complete( aCompletionCode );
       
   338     if ( !iConnectRequestComplete )
       
   339         iConnectRequest.Complete( aCompletionCode ); // error when making connection
       
   340     iWriteRequestComplete = ETrue;
       
   341     iReadRequestComplete = ETrue;
       
   342     iConnectRequestComplete = ETrue;
       
   343     delete iIncomingDataBuf;
       
   344     iIncomingDataBuf = NULL;
       
   345     delete iSendBuffer;
       
   346     iSendBuffer = NULL;
       
   347     iIncomingDataBuf = HBufC8::New(KIncomingDataBufSize);
       
   348     LOGFW(DebugLog(_L("CHtiBtCommServerSession: ResetAll(): Done")))
       
   349     }
       
   350 
       
   351 /*---------------------------------------------------------------------------*/
       
   352 void CHtiBtCommServerSession::ConnectedToServer(TInt aError)
       
   353     {
       
   354     // Connected to server. Reading has been started.
       
   355     LOGFW(InfoLog(_L("CHtiBtCommServerSession: ConnectedToServer: connected to remote host")))
       
   356     iConnectRequestComplete = ETrue;
       
   357     iConnectRequest.Complete( aError );
       
   358     }
       
   359 
       
   360 /*---------------------------------------------------------------------------*/
       
   361 void CHtiBtCommServerSession::DisconnectedFromServer()
       
   362     {
       
   363     LOGFW(InfoLog(_L("CHtiBtCommServerSession: DisconnectedFromServer: disconnected from remote host")))
       
   364     ResetAll( KErrDisconnected );
       
   365     }
       
   366 
       
   367 /*---------------------------------------------------------------------------*/
       
   368 void CHtiBtCommServerSession::DataFromServer(const TDesC8& aData)
       
   369     {
       
   370     LOGFW(DebugLog(_L("CHtiBtCommServerSession: DataFromServer: %d bytes"), aData.Length()))
       
   371     TPtr8 ptr = iIncomingDataBuf->Des();
       
   372     if ( aData.Length() > ptr.MaxLength() - ptr.Length() )
       
   373         PanicClient( KErrUnderflow ); // Client is reading too slowly
       
   374 
       
   375     ptr.Append( aData );
       
   376     TryCompleteReadRequest();
       
   377     LOGFW(DebugLog(_L("CHtiBtCommServerSession: DataFromServer: done"), aData.Length()))
       
   378     }
       
   379 
       
   380 /*---------------------------------------------------------------------------*/
       
   381 void CHtiBtCommServerSession::AllBufferedDataSent()
       
   382     {
       
   383     LOGFW(DebugLog(_L("CHtiBtCommServerSession: AllBufferedDataSent")))
       
   384     if ( !iWriteRequestComplete )
       
   385         {
       
   386         // iBtClient has sent all of its data and is ready to send more.
       
   387         TPtr8 ptr = iSendBuffer->Des();
       
   388         TRAPD( err, iBtClient->SendL( ptr ); )
       
   389         iWriteRequest.Complete( err );
       
   390         iWriteRequestComplete = ETrue;
       
   391         delete iSendBuffer;
       
   392         iSendBuffer = NULL;
       
   393         }
       
   394     LOGFW(DebugLog(_L("CHtiBtCommServerSession: AllBufferedDataSent: Done")))
       
   395     }
       
   396 
       
   397 /*---------------------------------------------------------------------------*/
       
   398 void CHtiBtCommServerSession::TryCompleteReadRequest()
       
   399     {
       
   400     LOGFW(DebugLog(_L("CHtiBtCommServerSession: TryCompleteReadRequest")))
       
   401     TPtr8 ptr = iIncomingDataBuf->Des();
       
   402 
       
   403     if ( iReadRequestComplete || ptr.Length() == 0 )
       
   404         {
       
   405         LOGFW(DebugLog(_L("CHtiBtCommServerSession: TryCompleteReadRequest: Nothing to complete")))
       
   406         return; // No outstanding client request to complete
       
   407         }
       
   408 
       
   409     TInt dataMaxLength = (TUint16)iReadRequest.GetDesMaxLength(0); //first message slot
       
   410     TPtrC8 dataToClient = ptr.Left(dataMaxLength);
       
   411     TRAPD(err, iReadRequest.WriteL(0, dataToClient);)
       
   412 
       
   413     ptr.Delete(0, dataToClient.Length());
       
   414     iReadRequest.Complete(err);
       
   415     iReadRequestComplete = ETrue;
       
   416     LOGFW(DebugLog(_L("CHtiBtCommServerSession: TryCompleteReadRequest: Done")))
       
   417     }
       
   418 
       
   419 // End of file