diff -r 000000000000 -r 29b1cd4cb562 bluetoothcommsprofiles/btpan/bnep/CSocketWriter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetoothcommsprofiles/btpan/bnep/CSocketWriter.cpp Fri Jan 15 08:13:17 2010 +0200 @@ -0,0 +1,156 @@ +// Copyright (c) 2004-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: +// + +/** + @file + @internalComponent +*/ + +#include +#include "CBnepLink.h" +#include "CSocketWriter.h" +#include "bneputils.h" + +#ifdef __FLOG_ACTIVE +_LIT8(KLogComponent, LOG_COMPONENT_PAN_BNEP); +#endif + +CSocketWriter::CSocketWriter (RInternalSocket& aSocket, CBnepLink& aOwner) + : CActive(EPriorityHigh), iSocket(aSocket), iBnepLink(aOwner) + { + LOG_FUNC + CActiveScheduler::Add(this); + } + +/** + Cancels any pending writes. + @internalComponent +*/ +CSocketWriter::~CSocketWriter() + { + LOG_FUNC + Cancel(); + + iPendingWriteData.Free(); + } + +/** + Create the socket writer + @internalComponent +*/ +CSocketWriter* CSocketWriter::NewL (RInternalSocket& aSocket, CBnepLink& aOwner) + { + LOG_STATIC_FUNC + CSocketWriter* self = new(ELeave) CSocketWriter(aSocket, aOwner); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/** + Attempt to write a buffer. + @return KErrNone if successful or a system-wide error code + @internalComponent +*/ +TInt CSocketWriter::Write (RMBufChain& aChain) + { + LOG_FUNC + if (aChain.Length() > KBnepMTU) + { + LOG(_L8("Length greater than expected MTU!")); + aChain.Free(); + return KErrTooBig; + } + if (IsActive()) + { + if(iQueueSize < KMaxSocketWriterQueueSize) + { + iQueue.Append(aChain); + iQueueSize++; + return KErrNone; + } + else + { + LOG(_L8("Bnep::ESocketWriterQueueOverflow")); + aChain.Free(); + return KErrOverflow; + } + } + LOG1(_L8("Length %d"), aChain.Length()); + + __ASSERT_DEBUG(iPendingWriteData.IsEmpty(), BnepUtils::Panic(Bnep::ESocketWriterQueueOverflow)); + iPendingWriteData.Assign(aChain); + iSocket.Write(iPendingWriteData, iStatus); + + SetActive(); + return KErrNone; + } + +/** + Does nothing + @internalComponent +*/ +void CSocketWriter::ConstructL () + { + LOG_FUNC + } + +/** + Checks iQueue for outstanding buffers and writes the first + if it exists. + @internalComponent +*/ +void CSocketWriter::RunL () + { + LOG_FUNC + // Check if the completed write was a success. + if(iStatus.Int() != KErrNone) + { + // The write failed - clear the pending write data. + LOG1(_L8("CSocketWriter::RunL completed with error: %d"), iStatus.Int()); + iPendingWriteData.Free(); + } + + __ASSERT_DEBUG(iPendingWriteData.IsEmpty(), BnepUtils::Panic(Bnep::ESocketWriterQueueOverflow)); + + if(!iQueue.IsEmpty()) + { + RMBufChain item; + //Check on return value of iQueue.Remove() is unnecessary, since we've checked iQueue.IsEmpty() + static_cast(iQueue.Remove(item)); + iQueueSize--; + Write(item); + } + else + { + iQueueSize = 0; // To make sure that we are always in sync + } + } + +/** + Cancel write. + @internalComponent +*/ +void CSocketWriter::DoCancel () + { + LOG_FUNC + iSocket.CancelWrite(); + + // Free the pending data buffer to aviod asserting when the next Write operation + // is performed. + + iPendingWriteData.Free(); + }