// 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:
// Provides the AVCTP Packet classes
// 
//

/**
 @file
 @internalComponent
*/

#ifndef AVCTPPACKET_H
#define AVCTPPACKET_H

#include <es_mbuf.h>

#include "avctpconstants.h"
#include "avctppacketstatics.h"

// Forward definitions
class TAvctpHeaderInfo;
class TAvctpNormalHeaderInfo;
class TAvctpStartHeaderInfo;

class RMBufChain;

NONSHARABLE_CLASS(CAvctpPacket) : public CBase
/**
Static methods to help parse an AVCTP packet.

  @internalComponent
*/
	{
public:
	static TInt ParseHeader(const RMBufChain& aData, TAvctpStartHeaderInfo& aHeaderInfo);
	static TPtrC8 GetHeader(const RMBufChain& aChain);
	
	static TInt ParseNormalHeader(const TDesC8& aData, TAvctpNormalHeaderInfo& aHeaderInfo);
	static TInt ParseStartHeader(const TDesC8& aData, TAvctpStartHeaderInfo& aHeaderInfo);

	static TInt CheckNormalHeaderInfo(const TAvctpNormalHeaderInfo& aHeaderInfo);
	static TInt CheckStartHeaderInfo(const TAvctpStartHeaderInfo& aHeaderInfo);

	};
	

/**
Contains the common information given in all AVCTP packet headers
@internalComponent.

This class by itself represents the headers of Continue and End 
packets.
*/
NONSHARABLE_CLASS(TAvctpHeaderInfo)
	{
public:
	inline TAvctpHeaderInfo();
	inline TAvctpHeaderInfo(SymbianAvctp::TTransactionLabel aTransactionLabel,
							SymbianAvctp::TPacketType aPktType,
							SymbianAvctp::TMessageType aMsgType);
	inline SymbianAvctp::TPduHeaderLength HeaderLength() const;

public:
	SymbianAvctp::TTransactionLabel iTransactionLabel;
	SymbianAvctp::TPacketType iPktType;
	SymbianAvctp::TMessageType iMsgType;
	};

/**
Contains the information given in a AVCTP normal packet header
@internalComponent
*/
NONSHARABLE_CLASS(TAvctpNormalHeaderInfo) : public TAvctpHeaderInfo
	{
public:
	inline TAvctpNormalHeaderInfo();
	inline TAvctpNormalHeaderInfo(SymbianAvctp::TTransactionLabel aTransactionLabel,
								  SymbianAvctp::TPacketType aPktType,
								  SymbianAvctp::TMessageType aMsgType,
								  TBool aHasValidPid,
								  SymbianAvctp::TPid aPid);
public:
	TBool iHasValidPid;
	SymbianAvctp::TPid iPid;
	};
	
/**
Contains the information given in a AVCTP start packet header
@internalComponent
*/
NONSHARABLE_CLASS(TAvctpStartHeaderInfo) : public TAvctpNormalHeaderInfo
	{
public:
	inline TAvctpStartHeaderInfo();
	inline TAvctpStartHeaderInfo(SymbianAvctp::TTransactionLabel aTransactionLabel,
								 SymbianAvctp::TPacketType aPktType,
								 SymbianAvctp::TMessageType aMsgType,
								 TBool aHasValidPid,
								 SymbianAvctp::TPid aPid,
								 TUint aFragmentsInSdu);
public:
	TUint iFragmentsInSdu;
	};

// Forward Declaration
class HAvctpIncomingSdu;
class TAvctpOutboundQ;
		
/**
The sap uses this class to take owner ship of data coming down from esock
& que it.
*/
NONSHARABLE_CLASS(HAvctpOutgoingSdu) 
	{
friend class TAvctpOutboundQ;   // So it has access to iQueLink to do it's Q ordering & Dequeing
friend class CAvctpProtocol;   	// So it can Q the Sdus

public:
	static HAvctpOutgoingSdu* NewL(const TAvctpNormalHeaderInfo& aHeaderInfo,
							 	   const TBTDevAddr& aAddr,
					 		 	   RMBufChain& aData);
					 		 	   
	static HAvctpOutgoingSdu* NewIpidResponseL(const HAvctpIncomingSdu& aIncomingSdu, TInt aChannel);
					 		 	   					 		 	   
	~HAvctpOutgoingSdu();

	inline const TBTDevAddr& BTAddr() const;
	inline TAvctpNormalHeaderInfo& HeaderInfo(); //non-const so fragmenter can update header
	inline RMBufChain& Data();
	inline void AddToQueue(TAvctpOutboundQ* aOutboundQ);
	inline TInt Channel() const;
	
private:
	inline HAvctpOutgoingSdu(const TAvctpNormalHeaderInfo& aHeaderInfo,
							 const TBTDevAddr& aAddr);	
	void ConstructL(RMBufChain& aData);

private:
	TDblQueLink iQueLink;
	TAvctpNormalHeaderInfo iHeaderInfo;
	TBTDevAddr iAddr;
	RMBufChain	iSduData;
	
	TAvctpOutboundQ* 	iOutboundQ; // unowned
	// iChannel is only used to carry the channel for the IPID responses. 
	// in all the other cases (i.e. for normal writing) the right fragmenter is picked up based on the current channel.
	// But IPID responses are generated by the protocol, asynchronously, so we save the channel value here.
	TUint				iChannel;
	};
	
/**
The sap uses this class to take owner ship of data coming up from below
& que it.
*/	
NONSHARABLE_CLASS(HAvctpIncomingSdu) 
	{
friend class CAvctpSap; 		// So it can Q the Sdus
	
public:
	inline HAvctpIncomingSdu(const TBTDevAddr& aAddr, 
							 RMBufChain& aSduData);	

	inline ~HAvctpIncomingSdu();
	inline const TBTDevAddr& BTAddr() const;
	inline const RMBufChain& Data() const;
private:
	TBTDevAddr	iAddr;
	RMBufChain	iSduData; // takes ownership of inbound chain
	TDblQueLink iQueLink;
	};	
	
#include "avctppacket.inl"
	
#endif // AVCTPPACKET_H
