--- /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 <bluetooth/logger.h>
+#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<KBTAddressLength> 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
+