bluetoothmgmt/bluetoothclientlib/avctpservices/avctpreceiver.cpp
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @internalTechnology
       
    19 */
       
    20 
       
    21 #include <bluetooth/logger.h>
       
    22 #include "avctpreceiver.h"
       
    23 #include "avctpcommon.h"
       
    24 #include "avctpbody.h"
       
    25 #include "avctpPriorities.h"
       
    26 #include "avctpserviceutils.h"
       
    27 
       
    28 #ifdef __FLOG_ACTIVE
       
    29 _LIT8(KLogComponent, LOG_COMPONENT_AVCTP_SERVICES);
       
    30 #endif
       
    31 
       
    32 using namespace SymbianAvctp;
       
    33 
       
    34 /**
       
    35 two-phase constructor
       
    36 @param aAvctpBody The class that provides access to the AVCTP client
       
    37 @leave systemwide reason
       
    38 @return pointer to newly created object
       
    39 @internalTechnology
       
    40 */
       
    41 CAvctpReceiver* CAvctpReceiver::NewL(MAvctpEventNotify& aNotify, RSocket& aAvctpSocket, TPid aPid)
       
    42 	{
       
    43 	LOG_STATIC_FUNC
       
    44 
       
    45 	CAvctpReceiver* self = CAvctpReceiver::NewLC(aNotify, aAvctpSocket, aPid);
       
    46 	CleanupStack::Pop(self);
       
    47 	return self;
       
    48 	}
       
    49 
       
    50 /**
       
    51 two-phase constructor, leaves object on cleanupstack
       
    52 @param aAvctpBody The class that provides access to the AVCTP client
       
    53 @leave systemwide reason
       
    54 @return pointer to newly created object
       
    55 @internalTechnology
       
    56 */
       
    57 CAvctpReceiver* CAvctpReceiver::NewLC(MAvctpEventNotify& aNotify, RSocket& aAvctpSocket, TPid aPid)
       
    58 	{
       
    59 	LOG_STATIC_FUNC
       
    60 
       
    61 	CAvctpReceiver* self = new(ELeave) CAvctpReceiver(aNotify, aAvctpSocket, aPid);
       
    62 	CleanupStack::PushL(self);
       
    63 	self->ConstructL();
       
    64 	return self;
       
    65 	}
       
    66 
       
    67 /**
       
    68 c'tor
       
    69 */
       
    70 CAvctpReceiver::CAvctpReceiver(MAvctpEventNotify& aNotify, RSocket& aAvctpSocket, TPid aPid) : 
       
    71 	CActive(KDataPlanePriority), 
       
    72 	iNotify(aNotify),
       
    73 	iAvctpSocket(aAvctpSocket),
       
    74 	iRecvState(EWaitingForPktHeader),
       
    75 	iRecvPtr(NULL, 0),
       
    76 	iPid(aPid)
       
    77 	{
       
    78 	LOG_FUNC
       
    79 	}
       
    80 
       
    81 void CAvctpReceiver::ConstructL()
       
    82 	{
       
    83 	LOG_FUNC
       
    84 	iRecvBuf = HBufC8::NewMaxL(ENormalHeaderLength);
       
    85 	iRecvBuf->Des().SetMax();
       
    86 	CActiveScheduler::Add(this);
       
    87 	ReceiveL(EWaitingForPktHeader);
       
    88 	}
       
    89 
       
    90 /**
       
    91 d'tor
       
    92 */
       
    93 CAvctpReceiver::~CAvctpReceiver()
       
    94 	{
       
    95 	LOG_FUNC
       
    96 
       
    97 	Cancel();
       
    98 	delete iRecvBuf;
       
    99 	}
       
   100 
       
   101 inline void CAvctpReceiver::NotifyMessageReceived(const TBTDevAddr& aBTDevice,
       
   102 									   		  SymbianAvctp::TTransactionLabel aTransactionLabel,
       
   103 									   		  SymbianAvctp::TMessageType aType,
       
   104 									   		  TBool aIpidBitSet,
       
   105 							 		   		  const TDesC8& aMessageInformation)
       
   106 	{
       
   107 	LOG_FUNC
       
   108 	__ASSERT_BTADDR(aBTDevice);
       
   109 	SymbianAvctp::AssertValidTransactionLabel(aTransactionLabel);
       
   110 	__ASSERT_DEBUG(aType == SymbianAvctp::ECommand || aType == SymbianAvctp::EResponse, Panic(::EAvctpInvalidMessageType));
       
   111 	
       
   112 	iNotify.MaenMessageReceivedIndicate(aBTDevice, aTransactionLabel, aType, aIpidBitSet, aMessageInformation);
       
   113 	}
       
   114 	
       
   115 //
       
   116 // Function that issues RecvFrom 
       
   117 
       
   118 /**
       
   119 Requests data from the Avctp Sap
       
   120 When the async Recv completes, iXfrLength will contain the remaining amount of data
       
   121 in the same packet that we've not yet got.
       
   122 */
       
   123 void CAvctpReceiver::ReceiveL(TRecvState aNextState, TInt aBufLen)
       
   124 	{
       
   125 	LOG_FUNC
       
   126 	//Make sure iRecvBuf isn't NULL before using it
       
   127 	if((!iRecvBuf) || (iRecvBuf->Des().MaxLength() < aBufLen)) 
       
   128 		{
       
   129 		// Don't ReAlloc cause that copies across the old data which we don't want
       
   130 		delete iRecvBuf; // free previous data
       
   131 		iRecvBuf = NULL;
       
   132 		iRecvBuf = HBufC8::NewMaxL(aBufLen);
       
   133 		iRecvBuf->Des().SetMax();
       
   134 		}
       
   135 	iRecvPtr.Set(iRecvBuf->Des().MidTPtr(0, aBufLen));
       
   136 	iAvctpSocket.RecvFrom(iRecvPtr, iAddr, KSockReadContinuation, iStatus, iXfrLength);	
       
   137 	ChangeState(aNextState);
       
   138 	}
       
   139 
       
   140 //
       
   141 // Functions From CActive
       
   142 	
       
   143 void CAvctpReceiver::DoCancel()
       
   144 	{
       
   145 	LOG_FUNC
       
   146 
       
   147 	iAvctpSocket.CancelRecv();
       
   148 	}
       
   149 
       
   150 void CAvctpReceiver::RunL()
       
   151 	{
       
   152 	LOG_FUNC
       
   153 	LOG1(_L("iStatus.Int(): %d"), iStatus.Int())
       
   154 	
       
   155 	if (iStatus.Int() == KErrNone)
       
   156 		{
       
   157 		switch (iRecvState)
       
   158 			{
       
   159 			case EWaitingForPktHeader:
       
   160 				SetPacketInfo(iRecvPtr);
       
   161 				if (iXfrLength())
       
   162 					{
       
   163 					ReceiveL(EWaitingForMsgInfo, iXfrLength());												 
       
   164 					}
       
   165 				else // there was no message data
       
   166 					{
       
   167 					NotifyMessageReceived(TAvctpSockAddr::Cast(iAddr).BTAddr(), 
       
   168 													 iTransactionLabel, 
       
   169 													 iMessageType, 
       
   170 													 iIpidBitSet, 
       
   171 													 KNullDesC8);
       
   172 					ReceiveL(EWaitingForPktHeader);	
       
   173 					}
       
   174 				break;
       
   175 				
       
   176 			case EWaitingForMsgInfo:
       
   177 				NotifyMessageReceived(TAvctpSockAddr::Cast(iAddr).BTAddr(), 
       
   178 												 iTransactionLabel, 
       
   179 												 iMessageType, 
       
   180 												 iIpidBitSet, 
       
   181 												 iRecvPtr);
       
   182 				ReceiveL(EWaitingForPktHeader);
       
   183 				break;		
       
   184 					
       
   185 			default:
       
   186 				__ASSERT_ALWAYS(NULL, Panic(EAvctpUnrecognisedState));
       
   187 				break;
       
   188 			}
       
   189 		}
       
   190 	else if (iStatus.Int() != KErrCancel)
       
   191 		{
       
   192 		iNotify.MaenErrorNotify(TAvctpSockAddr::Cast(iAddr).BTAddr(), iStatus.Int());
       
   193 		}
       
   194 	// else ignore the KErrCancel since the cancelled request wasn't directly asked for by the client of RAvctp
       
   195 	}
       
   196 	
       
   197 TInt CAvctpReceiver::RunError(TInt aError)
       
   198 	{
       
   199 	LOG_FUNC
       
   200 
       
   201 	iNotify.MaenErrorNotify(TAvctpSockAddr::Cast(iAddr).BTAddr(), aError);
       
   202 	return KErrNone;	
       
   203 	}
       
   204 
       
   205 //
       
   206 // Other Functions
       
   207 
       
   208 void CAvctpReceiver::ChangeState(TRecvState aNextState)
       
   209 	{
       
   210 	LOG_FUNC
       
   211 	LOG2(_L("current State: %d, aNextState: %d"), iRecvState, aNextState)
       
   212 	
       
   213 	__ASSERT_DEBUG((iRecvState == EWaitingForPktHeader && aNextState == EWaitingForMsgInfo)   ||
       
   214 				   (iRecvState == EWaitingForPktHeader && aNextState == EWaitingForPktHeader) ||
       
   215 				   (iRecvState == EWaitingForMsgInfo &&   aNextState == EWaitingForPktHeader),
       
   216 				   Panic(EAvctpRecvBadStateTransition));
       
   217 	__ASSERT_ALWAYS(!IsActive(), Panic(EAvctpRecvBadStateTransition));
       
   218 	iRecvState = aNextState;
       
   219 	SetActive();
       
   220 	}
       
   221     
       
   222 void CAvctpReceiver::SetPacketInfo(TDes8& aHeader)
       
   223 	{
       
   224 	LOG_FUNC
       
   225 
       
   226 	__ASSERT_DEBUG(Pid(aHeader) == iPid, Panic(EAvctpIncorrectPid));
       
   227 	__ASSERT_DEBUG(PacketType(aHeader) == ENormalPkt, Panic(EAvctpPacketTypeNotNormal));
       
   228 				
       
   229 	iTransactionLabel = TransactionLabel(aHeader);
       
   230 	iMessageType = MessageType(aHeader);
       
   231 	iIpidBitSet = !IsValidPid(aHeader);
       
   232 	
       
   233   __DEBUG_ONLY
       
   234   		(
       
   235   		TBuf<KBTAddressLength> address;
       
   236   		TAvctpSockAddr::Cast(iAddr).BTAddr().GetReadable(address);
       
   237   		)
       
   238   	
       
   239   	LOG1(_L("BT Device 0x%S"), &address);
       
   240 	
       
   241 	LOG3(_L("iTransactionLabel: %d, iMessageType: %d, iIpidBitSet: %d"), iTransactionLabel, iMessageType, iIpidBitSet)
       
   242 	}
       
   243         	
       
   244 // EOF
       
   245