diff -r 000000000000 -r 29b1cd4cb562 bluetoothmgmt/bluetoothclientlib/avctpservices/avctpreceiver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetoothmgmt/bluetoothclientlib/avctpservices/avctpreceiver.cpp Fri Jan 15 08:13:17 2010 +0200 @@ -0,0 +1,245 @@ +// Copyright (c) 2005-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 + @internalTechnology +*/ + +#include +#include "avctpreceiver.h" +#include "avctpcommon.h" +#include "avctpbody.h" +#include "avctpPriorities.h" +#include "avctpserviceutils.h" + +#ifdef __FLOG_ACTIVE +_LIT8(KLogComponent, LOG_COMPONENT_AVCTP_SERVICES); +#endif + +using namespace SymbianAvctp; + +/** +two-phase constructor +@param aAvctpBody The class that provides access to the AVCTP client +@leave systemwide reason +@return pointer to newly created object +@internalTechnology +*/ +CAvctpReceiver* CAvctpReceiver::NewL(MAvctpEventNotify& aNotify, RSocket& aAvctpSocket, TPid aPid) + { + LOG_STATIC_FUNC + + CAvctpReceiver* self = CAvctpReceiver::NewLC(aNotify, aAvctpSocket, aPid); + CleanupStack::Pop(self); + return self; + } + +/** +two-phase constructor, leaves object on cleanupstack +@param aAvctpBody The class that provides access to the AVCTP client +@leave systemwide reason +@return pointer to newly created object +@internalTechnology +*/ +CAvctpReceiver* CAvctpReceiver::NewLC(MAvctpEventNotify& aNotify, RSocket& aAvctpSocket, TPid aPid) + { + LOG_STATIC_FUNC + + CAvctpReceiver* self = new(ELeave) CAvctpReceiver(aNotify, aAvctpSocket, aPid); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +/** +c'tor +*/ +CAvctpReceiver::CAvctpReceiver(MAvctpEventNotify& aNotify, RSocket& aAvctpSocket, TPid aPid) : + CActive(KDataPlanePriority), + iNotify(aNotify), + iAvctpSocket(aAvctpSocket), + iRecvState(EWaitingForPktHeader), + iRecvPtr(NULL, 0), + iPid(aPid) + { + LOG_FUNC + } + +void CAvctpReceiver::ConstructL() + { + LOG_FUNC + iRecvBuf = HBufC8::NewMaxL(ENormalHeaderLength); + iRecvBuf->Des().SetMax(); + CActiveScheduler::Add(this); + ReceiveL(EWaitingForPktHeader); + } + +/** +d'tor +*/ +CAvctpReceiver::~CAvctpReceiver() + { + LOG_FUNC + + Cancel(); + delete iRecvBuf; + } + +inline void CAvctpReceiver::NotifyMessageReceived(const TBTDevAddr& aBTDevice, + SymbianAvctp::TTransactionLabel aTransactionLabel, + SymbianAvctp::TMessageType aType, + TBool aIpidBitSet, + const TDesC8& aMessageInformation) + { + LOG_FUNC + __ASSERT_BTADDR(aBTDevice); + SymbianAvctp::AssertValidTransactionLabel(aTransactionLabel); + __ASSERT_DEBUG(aType == SymbianAvctp::ECommand || aType == SymbianAvctp::EResponse, Panic(::EAvctpInvalidMessageType)); + + iNotify.MaenMessageReceivedIndicate(aBTDevice, aTransactionLabel, aType, aIpidBitSet, aMessageInformation); + } + +// +// Function that issues RecvFrom + +/** +Requests data from the Avctp Sap +When the async Recv completes, iXfrLength will contain the remaining amount of data +in the same packet that we've not yet got. +*/ +void CAvctpReceiver::ReceiveL(TRecvState aNextState, TInt aBufLen) + { + LOG_FUNC + //Make sure iRecvBuf isn't NULL before using it + if((!iRecvBuf) || (iRecvBuf->Des().MaxLength() < aBufLen)) + { + // Don't ReAlloc cause that copies across the old data which we don't want + delete iRecvBuf; // free previous data + iRecvBuf = NULL; + iRecvBuf = HBufC8::NewMaxL(aBufLen); + iRecvBuf->Des().SetMax(); + } + iRecvPtr.Set(iRecvBuf->Des().MidTPtr(0, aBufLen)); + iAvctpSocket.RecvFrom(iRecvPtr, iAddr, KSockReadContinuation, iStatus, iXfrLength); + ChangeState(aNextState); + } + +// +// Functions From CActive + +void CAvctpReceiver::DoCancel() + { + LOG_FUNC + + iAvctpSocket.CancelRecv(); + } + +void CAvctpReceiver::RunL() + { + LOG_FUNC + LOG1(_L("iStatus.Int(): %d"), iStatus.Int()) + + if (iStatus.Int() == KErrNone) + { + switch (iRecvState) + { + case EWaitingForPktHeader: + SetPacketInfo(iRecvPtr); + if (iXfrLength()) + { + ReceiveL(EWaitingForMsgInfo, iXfrLength()); + } + else // there was no message data + { + NotifyMessageReceived(TAvctpSockAddr::Cast(iAddr).BTAddr(), + iTransactionLabel, + iMessageType, + iIpidBitSet, + KNullDesC8); + ReceiveL(EWaitingForPktHeader); + } + break; + + case EWaitingForMsgInfo: + NotifyMessageReceived(TAvctpSockAddr::Cast(iAddr).BTAddr(), + iTransactionLabel, + iMessageType, + iIpidBitSet, + iRecvPtr); + ReceiveL(EWaitingForPktHeader); + break; + + default: + __ASSERT_ALWAYS(NULL, Panic(EAvctpUnrecognisedState)); + break; + } + } + else if (iStatus.Int() != KErrCancel) + { + iNotify.MaenErrorNotify(TAvctpSockAddr::Cast(iAddr).BTAddr(), iStatus.Int()); + } + // else ignore the KErrCancel since the cancelled request wasn't directly asked for by the client of RAvctp + } + +TInt CAvctpReceiver::RunError(TInt aError) + { + LOG_FUNC + + iNotify.MaenErrorNotify(TAvctpSockAddr::Cast(iAddr).BTAddr(), aError); + return KErrNone; + } + +// +// Other Functions + +void CAvctpReceiver::ChangeState(TRecvState aNextState) + { + LOG_FUNC + LOG2(_L("current State: %d, aNextState: %d"), iRecvState, aNextState) + + __ASSERT_DEBUG((iRecvState == EWaitingForPktHeader && aNextState == EWaitingForMsgInfo) || + (iRecvState == EWaitingForPktHeader && aNextState == EWaitingForPktHeader) || + (iRecvState == EWaitingForMsgInfo && aNextState == EWaitingForPktHeader), + Panic(EAvctpRecvBadStateTransition)); + __ASSERT_ALWAYS(!IsActive(), Panic(EAvctpRecvBadStateTransition)); + iRecvState = aNextState; + SetActive(); + } + +void CAvctpReceiver::SetPacketInfo(TDes8& aHeader) + { + LOG_FUNC + + __ASSERT_DEBUG(Pid(aHeader) == iPid, Panic(EAvctpIncorrectPid)); + __ASSERT_DEBUG(PacketType(aHeader) == ENormalPkt, Panic(EAvctpPacketTypeNotNormal)); + + iTransactionLabel = TransactionLabel(aHeader); + iMessageType = MessageType(aHeader); + iIpidBitSet = !IsValidPid(aHeader); + + __DEBUG_ONLY + ( + TBuf address; + TAvctpSockAddr::Cast(iAddr).BTAddr().GetReadable(address); + ) + + LOG1(_L("BT Device 0x%S"), &address); + + LOG3(_L("iTransactionLabel: %d, iMessageType: %d, iIpidBitSet: %d"), iTransactionLabel, iMessageType, iIpidBitSet) + } + +// EOF +