diff -r 3406c99bc375 -r 07b41fa8d1dd hti/HtiFramework/src/HtiCommAdapter.cpp --- a/hti/HtiFramework/src/HtiCommAdapter.cpp Thu Jul 15 20:25:38 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; - } - }