--- a/hti/HtiFramework/src/HtiCommAdapter.cpp Tue Jul 06 16:05:13 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,556 +0,0 @@
-/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: CHtiCommAdapter implementation
-*
-*/
-
-
-#include "HtiCommAdapter.h"
-#include "HtiDispatcher.h"
-#include "HtiCommPluginInterface.h"
-#include "HtiMessage.h"
-#include "HtiNotifier.h"
-
-#include "HtiLogging.h"
-
-//default value for max message size for incoming messages
-//used if value in constructor is not valid (<0)
-const static TInt KMaxMessageSize = 10 * 1024; // 10 KB
-
-const static TInt KHtiCommPriority = 2;
-
-_LIT( KCommPanic, "HtiCommAdapter" );
-
-CHtiCommAdapter* CHtiCommAdapter::NewLC( CHTICommPluginInterface* aCommPlugin,
- CHtiDispatcher* aDispatcher, TInt aMaxMsgSize )
- {
- CHtiCommAdapter* obj = new (ELeave) CHtiCommAdapter( aDispatcher,
- aCommPlugin, aMaxMsgSize );
- CleanupStack::PushL( obj );
- obj->ConstructL();
- return obj;
- }
-
-CHtiCommAdapter* CHtiCommAdapter::NewL( CHTICommPluginInterface* aCommPlugin,
- CHtiDispatcher* aDispatcher, TInt aMaxMsgSize )
- {
- CHtiCommAdapter* obj = NewLC( aCommPlugin, aDispatcher, aMaxMsgSize );
- CleanupStack::Pop();
- return obj;
- }
-
-CHtiCommAdapter::CHtiCommAdapter( CHtiDispatcher* aDispatcher,
- CHTICommPluginInterface* aCommPlugin,
- TInt aMaxMsgSize )
- :CActive( KHtiCommPriority ),
- iState( EIdle ),
- iDispatcher( aDispatcher ),
- iCommPlugin( aCommPlugin ),
- iBufferPtr( NULL, 0 ),
- iMsgToReceive( NULL ),
- iMsgToSend( NULL ),
- iMsgToSendPtr( NULL, 0 ),
- iMsgToSendOffset( 0 ),
- iSkipLength( 0 ),
- iMaxMessageSize( aMaxMsgSize > 0 ? aMaxMsgSize : KMaxMessageSize )
- {
- HTI_LOG_FORMAT( "MaxMsgSize %d", iMaxMessageSize );
- };
-
-CHtiCommAdapter::~CHtiCommAdapter()
- {
- HTI_LOG_FUNC_IN( "CHtiCommAdapter::~CHtiCommAdapter" );
- Cancel();
-
- delete iBuffer;
- delete iLeftovers;
-
- delete iMsgToReceive;
- delete iMsgToSend;
-
- HTI_LOG_FUNC_OUT( "CHtiCommAdapter::~CHtiCommAdapter" );
- }
-
-void CHtiCommAdapter::ConstructL()
- {
- HTI_LOG_FUNC_IN( "CHtiCommAdapter::ConstructL" );
-
- //allocate recommended buffer plus some extra space
- //needed to handle msg parsing
- iBuffer = HBufC8::NewL( iCommPlugin->GetReceiveBufferSize() +
- CHtiMessage::MinHeaderSize() );
-
- iBuffer->Des().SetLength( iCommPlugin->GetReceiveBufferSize() );
- iBufferPtr.Set( iBuffer->Des().LeftTPtr(
- iCommPlugin->GetReceiveBufferSize() ) );
-
- iLeftovers = HBufC8::NewL( CHtiMessage::MinHeaderSize() );
-
- CActiveScheduler::Add( this );
- HTI_LOG_FUNC_OUT( "CHtiCommAdapter::ConstructL" );
- }
-
-void CHtiCommAdapter::ReceiveMessage()
- {
- ReceiveMessage( EFalse );
- }
-
-void CHtiCommAdapter::ReceiveMessage( TBool aContinue )
- {
- HTI_LOG_FUNC_IN( "CHtiCommAdapter::ReceiveMessage" );
-
- iState = aContinue?EReceivingCont:EReceiving;
- iCommPlugin->Receive( iBufferPtr, iStatus );
- SetActive();
-
- HTI_LOG_FUNC_OUT( "CHtiCommAdapter::ReceiveMessage" );
- }
-
-void CHtiCommAdapter::SendMessage( CHtiMessage* aMessage )
- {
- HTI_LOG_FUNC_IN( "CCommAdapter::SendMessage" );
- iState = ESending;
- if ( aMessage != NULL )
- {
- HTI_LOG_TEXT( "send first packet" );
- iMsgToSend = aMessage;
- iMsgToSendOffset = 0;
-
- //first send header
- iMsgToSendPtr.Set( iMsgToSend->Header() );
- }
- else if ( iMsgToSend != NULL )
- {
- //send next chunk
- if ( iMsgToSend->BodySize() <=
- ( iMsgToSendOffset + iCommPlugin->GetSendBufferSize() ) )
- {
- HTI_LOG_TEXT( "send remainder" );
- iMsgToSendPtr.Set( iMsgToSend->Body().Mid( iMsgToSendOffset ) );
- iMsgToSendOffset = iMsgToSend->BodySize(); //last sending
- }
- else
- {
- HTI_LOG_TEXT( "send packet" );
- iMsgToSendPtr.Set( iMsgToSend->Body().Mid( iMsgToSendOffset,
- iCommPlugin->GetSendBufferSize() ) );
- iMsgToSendOffset += iCommPlugin->GetSendBufferSize();
- }
- }
- else
- {
- User::Panic( KCommPanic, KErrGeneral );
- }
-
- iCommPlugin->Send( iMsgToSendPtr, iStatus );
- SetActive();
-
- HTI_LOG_FUNC_OUT( "CCommAdapter::SendMessage" );
- }
-
-void CHtiCommAdapter::Reset()
- {
- HTI_LOG_FUNC_IN( "CHtiCommAdapter::Reset" );
- Cancel();
- //receiving msg
- delete iMsgToReceive;
- iMsgToReceive = NULL;
-
- //send msg
- delete iMsgToSend;
- iMsgToSend = NULL;
- iMsgToSendOffset = 0;
-
- //empty buffers
- iLeftovers->Des().Zero();
- iBuffer->Des().Zero();
- iSkipLength = 0;
-
- //set idle
- iState = EIdle;
-
- HTI_LOG_FUNC_OUT( "CHtiCommAdapter::Reset" );
- }
-
-void CHtiCommAdapter::RunL()
- {
- HTI_LOG_FUNC_IN( "CHtiCommAdapter::RunL" );
- HTI_LOG_FORMAT( "iStatus %d", iStatus.Int() );
-
- //handle reset code common for all states
- if ( iStatus == KErrComModuleReset )
- {
- HTI_LOG_TEXT( "Reset received from comm module" );
- //reset dispatcher
- iDispatcher->Reset();
- //dispatcher will call Reset() for comm adapters and reissue requests
- return;
- }
-
- //check for critical (unrecoverable) communication errors
- else if ( iStatus == KErrServerTerminated )
- {
- if ( iDispatcher->GetShowErrorDialogs() )
- {
- User::Panic( KCommPanic, KErrServerTerminated );
- }
- else
- {
- User::Exit( KErrServerTerminated );
- }
- }
- // USB errors from d32usbc.h
- else if ( -6700 > iStatus.Int() && iStatus.Int() > -6712 )
- {
- if(iDispatcher->CommReconnect())
- {
- return;
- }
-
- if ( iDispatcher->GetShowErrorDialogs() )
- {
- TBuf<48> errorText;
- errorText.Append( _L( "USB connection lost (" ) );
- errorText.AppendNum( iStatus.Int() );
- errorText.Append( _L( "). HTI stopped." ) );
- CHtiNotifier::ShowErrorL( errorText );
- }
- User::Exit( KErrDisconnected );
- }
- else if ( iStatus == KErrDisconnected )
- {
- // This happens if Bluetooth connection is lost.
- if(iDispatcher->CommReconnect())
- {
- return;
- }
-
- if ( iDispatcher->GetShowErrorDialogs() )
- {
- CHtiNotifier::ShowErrorL(
- _L( "Connection lost. HTI stopped." ), KErrDisconnected );
- }
- User::Exit( KErrDisconnected );
- }
-
- switch ( iState )
- {
- case EReceiving:
- //process
- HTI_LOG_TEXT( "EReceiving" );
- if ( iStatus == KErrNone )
- {
- iBuffer->Des().SetLength( iBufferPtr.Length() );
- TRAPD( err, HandleReceiveL() );
- if ( err != KErrNone )
- {
- HTI_LOG_FORMAT( "Error in HandleReceiveL %d", err );
-
- delete iMsgToReceive;
- iMsgToReceive = NULL;
-
- iDispatcher->Notify( err );
-
- ReceiveMessage();
- }
- }
- else
- {
- HTI_LOG_FORMAT( "Error %d, reissue request", iStatus.Int() );
- iDispatcher->Notify( iStatus.Int() );
- User::After(2000000);
- ReceiveMessage();
- }
- break;
- case EReceivingCont:
- //process
- HTI_LOG_TEXT( "EReceivingCont" );
- if ( iStatus == KErrNone )
- {
- iBuffer->Des().SetLength( iBufferPtr.Length() );
- TRAPD( err, HandleReceiveContL() );
- if ( err != KErrNone )
- {
- HTI_LOG_FORMAT( "Error in HandleReceiveContL %d", err );
-
- delete iMsgToReceive;
- iMsgToReceive = NULL;
-
- iDispatcher->Notify( err );
-
- ReceiveMessage();
- }
- }
- else
- {
- HTI_LOG_FORMAT( "Error %d, reissue request", iStatus.Int() );
- HTI_LOG_TEXT( "and dismiss received HTI msg beginning" );
- delete iMsgToReceive;
- iMsgToReceive = NULL;
-
- iDispatcher->Notify( iStatus.Int() );
- User::After(2000000);
- ReceiveMessage();
- }
- break;
- case ESending:
- HTI_LOG_TEXT( "ESending" );
- if ( iStatus == KErrNone )
- {
- HandleSend();
- }
- else
- {
- HTI_LOG_FORMAT( "Error %d, stop sending, go to EIdle", iStatus.Int() );
-
- delete iMsgToSend;
- iMsgToSend = NULL;
- iMsgToSendOffset = 0;
- iState = EIdle;
-
- iDispatcher->Notify( iStatus.Int() );
- }
- break;
- case EIdle:
- //ERROR
- HTI_LOG_TEXT( "EIdle" );
- User::Panic( KCommPanic, KErrGeneral );
- break;
- default:
- //ERROR
- HTI_LOG_TEXT( "default" );
- User::Panic( KCommPanic, KErrGeneral );
- };
-
- HTI_LOG_FUNC_OUT( "CHtiCommAdapter::RunL" );
- }
-
-void CHtiCommAdapter::HandleReceiveL()
- {
- TBool toContinue = EFalse; //for reissuing state
-
- if ( iLeftovers->Length() > 0 )
- {
- HTI_LOG_TEXT( "handle leftovers" );
- //if something left from previous time
- //insert it to the buffer beggining
- //check that there is enough space (should be)
- if ( iBuffer->Length() + iLeftovers->Length() <=
- iBuffer->Des().MaxLength() )
- {
- iBuffer->Des().Insert( 0, *iLeftovers );
- }
- else
- {
- //error
- HTI_LOG_TEXT( "iMsgToReceive contain too much leftovers, drop them" );
- }
-
- iLeftovers->Des().Zero();
- }
-
- //use loop cause can be several HTI messages in iBuffer
- while ( iBuffer->Length() >= CHtiMessage::MinHeaderSize() )
- {
- HTI_LOG_FORMAT( "iBuffer.Length() %d", iBuffer->Length() );
- HTI_LOG_TEXT( "check header" );
-
- if ( CHtiMessage::CheckValidHtiHeader( *iBuffer ) )
- {
- HTI_LOG_TEXT( "valid header" );
- TInt msgSize = CHtiMessage::Size( *iBuffer );
- HTI_LOG_FORMAT( "msgSize %d", msgSize );
- HTI_LOG_HEX( iBuffer->Des().Ptr(), 14 );
-
- __ASSERT_ALWAYS( iMsgToReceive == NULL,
- User::Panic( KCommPanic, KErrGeneral ) );
-
- //check msgSize is acceptable
- if ( msgSize > iMaxMessageSize )
- {
- //send err message
- iDispatcher->DispatchOutgoingErrorMessage( EHtiErrBigMessage );
- iSkipLength = msgSize;
- }
- else if ( msgSize > iDispatcher->GetFreeMemory() )
- {
- //send err message
- iDispatcher->DispatchOutgoingErrorMessage( EHtiErrNoMemory );
- iSkipLength = msgSize;
- }
- else
- {
- iMsgToReceive = CHtiMessage::NewL( *iBuffer );
- }
-
- if ( iMsgToReceive == NULL )
- {
- HTI_LOG_TEXT( "skip message" );
- if ( iSkipLength > iBuffer->Length() )
- {
- iSkipLength -= iBuffer->Length();
- iBuffer->Des().Zero();
- // and continue to receive HTI message
- //switch state to EReceiveCont
- toContinue = ETrue;
- }
- else
- {
- //should not be here, but just in case
- iBuffer->Des().Delete( 0, iSkipLength );
- iSkipLength = 0;
- }
- }
- else if ( iMsgToReceive->IsBodyComplete() )
- {
- HTI_LOG_TEXT( "handle small message" );
- //iMsgToReceive is already contain whole HTI message
- iDispatcher->DispatchIncomingMessage( iMsgToReceive );
-
- //delete sent msg from buffer (and procces the rest)
- iBuffer->Des().Delete( 0, iMsgToReceive->Size() );
- iMsgToReceive = NULL;
- }
- else
- {
- HTI_LOG_TEXT( "start receive big message" );
- //clear it to leave loop
- iBuffer->Des().Zero();
- // and continue to receive HTI message
- //switch state to EReceiveCont
- toContinue = ETrue;
- }
- }
- else
- {
- HTI_LOG_TEXT( "invalid header, dismiss buffer and reissue request" );
- HTI_LOG_HEX( iBuffer->Des().Ptr(), 14 );
- // clear all buffer cause don't know where is valid header starts
- // and wait for the next packet
- iBuffer->Des().Zero(); //to leave loop
- }
- }
-
- if ( iBuffer->Length() > 0 )
- {
- HTI_LOG_FORMAT( "copy leftovers %d", iBuffer->Length() );
- //header beggining left in the buffer
- //copy it to iLeftovers
- ( *iLeftovers ) = ( *iBuffer );
- }
- //reissue request
- ReceiveMessage( toContinue );
- }
-
-void CHtiCommAdapter::HandleReceiveContL()
- {
- HTI_LOG_FORMAT( "In buffer: %d", iBuffer->Length() );
- TBool toContinue = ETrue;
-
- if ( iMsgToReceive != NULL && iSkipLength == 0 )
- {
- //add new packet to a message
- TInt copyLen = iMsgToReceive->AddToBody( *iBuffer );
-
- //delete what we copied to the message
- iBuffer->Des().Delete( 0, copyLen );
-
- if ( iMsgToReceive->IsBodyComplete() )
- {
- HTI_LOG_FORMAT( "body complete: %d", iMsgToReceive->BodySize() );
-
- iDispatcher->DispatchIncomingMessage( iMsgToReceive );
- iMsgToReceive = NULL;
-
- //message complete, go to state EReceive
- toContinue = EFalse;
- }
- }
- else if ( iSkipLength > 0 )
- {
- HTI_LOG_FORMAT( "continue skipping, remains %d", iSkipLength );
-
- if ( iSkipLength > iBuffer->Length() )
- {
- iSkipLength -= iBuffer->Length();
- iBuffer->Des().Zero();
- }
- else
- {
- //skip last bytes
- iBuffer->Des().Delete( 0, iSkipLength );
- iSkipLength = 0;
-
- toContinue = EFalse;
- }
- }
-
- if ( iBuffer->Length() > 0 )
- {
- //process remainder and reissue in HandleReceiveL()
- HandleReceiveL();
- }
- else
- {
- //reissue
- ReceiveMessage(toContinue);
- }
- }
-
-void CHtiCommAdapter::HandleSend()
- {
- if ( iMsgToSendOffset < iMsgToSend->BodySize() )
- {
- //reissuse sending
- SendMessage( NULL );
- }
- else
- {
- HTI_LOG_TEXT( "finish send, go to idle" );
- iMsgToSendOffset = 0;
- delete iMsgToSend;
- iMsgToSend = NULL;
- iState = EIdle;
- iDispatcher->Notify( KErrNone );
- }
- }
-
-TInt CHtiCommAdapter::RunError( TInt aError )
- {
- TInt err = aError;
- switch ( aError )
- {
- case KErrNoMemory:
- break;
- case KErrNotFound:
- break;
- }
- return err;
- }
-
-void CHtiCommAdapter::DoCancel()
- {
- switch ( iState )
- {
- case EReceiving:
- case EReceivingCont:
- iCommPlugin->CancelReceive();
- break;
- case ESending:
- iCommPlugin->CancelSend();
- break;
- default:
- break;
- }
- }