bluetooth/btstack/eirman/eirmansession.cpp
branchRCL_3
changeset 17 32ba20339036
parent 0 29b1cd4cb562
child 18 1f10b9300be6
--- a/bluetooth/btstack/eirman/eirmansession.cpp	Tue May 11 17:15:36 2010 +0300
+++ b/bluetooth/btstack/eirman/eirmansession.cpp	Tue May 25 13:54:55 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2007-2010 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"
@@ -32,19 +32,21 @@
 _LIT8(KLogComponent, LOG_COMPONENT_EIRMANAGER);
 #endif
 
-CEirManSession* CEirManSession::NewL(CEirManServer& aServer)
+CEirManSession* CEirManSession::NewL(CEirManServer& aServer, MEirSessionNotifier& aParent, TBool aInternalSession)
 	{
 	LOG_STATIC_FUNC
-	CEirManSession* self = new(ELeave) CEirManSession(aServer);
+	CEirManSession* self = new(ELeave) CEirManSession(aServer, aParent, aInternalSession);
 	CleanupStack::PushL(self);
 	self->ConstructL();
 	CleanupStack::Pop(self);
 	return self;
 	}
 
-CEirManSession::CEirManSession(CEirManServer& aServer)
+CEirManSession::CEirManSession(CEirManServer& aServer, MEirSessionNotifier& aParent, TBool aInternalSession)
 	: iEirManServer(aServer)
+	, iParent(aParent)
 	, iEirTag(EEirTagRESERVED)
+	, iInternalSession(aInternalSession)
 	{
 	LOG_FUNC
 	}
@@ -52,7 +54,7 @@
 void CEirManSession::ConstructL()
 	{
 	LOG_FUNC
-	iEirManServer.AddSession();
+	iEirManServer.AddSession(*this, iInternalSession);
 	}
 
 CEirManSession::~CEirManSession()
@@ -60,15 +62,154 @@
 	LOG_FUNC
 	// deregister any registered tag that may be registered
 	DeregisterTag();
+	iLink.Deque();
+	iEirManServer.DropSession(iInternalSession);
+	}
+
+void CEirManSession::RegisterTag(TEirTag aTag)
+	{
+	LOG_FUNC
+
+	LOG1(_L("CEirManSession::RegisterTag tag = %d"), aTag);
+
+	if(!(aTag >= EEirTagName && aTag < EEirTagRESERVED))
+		{
+		iParent.MesnRegisterComplete(KErrArgument);
+		}
+	else if(iEirTag != EEirTagRESERVED)
+		{
+		LOG1(_L("CEirManSession::RegisterTag ERROR, Tag in use: %d"), iEirTag);
+		iParent.MesnRegisterComplete(KErrInUse);
+		}
+	else
+		{
+		// Register this tag for callbacks
+		if(iEirManServer.EirFeatureState() == EEirFeatureReady)
+			{
+			// Eir is supported
+			TInt result = iEirManServer.EirManager().RegisterTag(aTag, *this);
+			if(result == KErrNone)
+				{
+				iEirTag = aTag;
+				}
+			iParent.MesnRegisterComplete(result);
+			}
+		else if(iEirManServer.EirFeatureState() == EEirFeaturePending)
+			{
+			// We don't know if eir is supported or not at this moment
+			iRegisterPending = ETrue;
+			iPendingEirTag = aTag;
+			}
+		else
+			{
+			// Eir is not supported
+			iParent.MesnRegisterComplete(KErrNotSupported);
+			}
+		}
+	}
+
+void CEirManSession::DeregisterTag()
+	{
+	LOG_FUNC
+	LOG1(_L("CEirManSession::DeregisterTag tag = %d"), iEirTag);
+	
+	if(iEirTag != EEirTagRESERVED)
+		{
+		// Deregister this tag for callbacks 
+		iEirManServer.EirManager().DeregisterTag(iEirTag);
+		iEirTag = EEirTagRESERVED;
+		}
+	}
+
+// Eir Server has tried to register tag
+void CEirManSession::NotifyEirFeatureState(TInt aResult)
+	{
+	LOG1(_L("Eir Server has been notified feature ready, result: %d"), aResult);
+	if(aResult == KErrNone && iRegisterPending)
+		{
+		__ASSERT_DEBUG(iEirManServer.EirFeatureState() == EEirFeatureReady, EIR_SESSION_PANIC(EEirSessionEirFeatureNotSupported));
+		TInt result = iEirManServer.EirManager().RegisterTag(iPendingEirTag, *this);
+		if(result == KErrNone)
+			{
+			iEirTag = iPendingEirTag;
+			}
+		iRegisterPending = EFalse;
+		iParent.MesnRegisterComplete(result);
+		}
+	else if(iRegisterPending)
+		{
+		iRegisterPending = EFalse;
+		iParent.MesnRegisterComplete(aResult);
+		}
+	}
+
+
+TInt CEirManSession::NewData(TInt aRequiredLength)
+	{
+	LOG_FUNC
+	return iEirManServer.EirManager().NewData(iEirTag, aRequiredLength);
+	}
+
+
+TInt CEirManSession::SetData(const TDesC8& aData, TEirDataMode aMode)
+	{
+	LOG_FUNC
+	return iEirManServer.EirManager().SetData(iEirTag, aData, aMode);
+	}
+
+// Callback from the EIR Manager
+void CEirManSession::MemnEirBlockAvailable(TEirTag aTag, TUint aSpaceForTag)
+	{
+	LOG_FUNC
+	LOG2(_L("CEirManSession::MemnEirBlockAvailable Tag: %d space: %d"), aTag, aSpaceForTag);
+
+	// Silently discard callbacks not containing our EIR Tag
+	if(aTag != iEirTag)
+		{
+		__ASSERT_DEBUG(EFalse, EIR_SESSION_PANIC(EEirSessionInvalidEirTag));
+		LOG3(_L("CEirManSession::MemnEirBlockAvailable early return: aTag: %d iEirTag: %d space: %d"), aTag, iEirTag, aSpaceForTag);
+		return;
+		}
+
+	iParent.MesnSpaceAvailable(aSpaceForTag);
+
+	}
+
+TEirTag CEirManSession::EirTag() const
+	{
+	return iEirTag;
+	}
+
+CEirManExternalSession* CEirManExternalSession::NewL(CEirManServer& aServer)
+	{
+	CEirManExternalSession* self = new(ELeave) CEirManExternalSession();
+	CleanupStack::PushL(self);
+	self->ConstructL(aServer);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CEirManExternalSession::CEirManExternalSession()
+	{
+	
+	}
+
+void CEirManExternalSession::ConstructL(CEirManServer& aServer)
+	{
+	iSession = CEirManSession::NewL(aServer, *this, EFalse);
+	}
+
+CEirManExternalSession::~CEirManExternalSession()
+	{
 	if(!iDataAvailableListenerMessage.IsNull())
 		{
 		// complete any outstanding messages.
 		iDataAvailableListenerMessage.Complete(KErrCancel);
 		}
-	iEirManServer.DropSession();
+	delete iSession;
 	}
 
-void CEirManSession::ServiceL(const RMessage2& aMessage)
+void CEirManExternalSession::ServiceL(const RMessage2& aMessage)
 	{
 	LOG_FUNC
 	LOG1(_L("CEirManSession::ServiceL aMessage.Function() = %d"), aMessage.Function());
@@ -109,83 +250,28 @@
 		}
 	}
 
-void CEirManSession::RegisterTag(const RMessage2& aMessage)
+void CEirManExternalSession::RegisterTag(const RMessage2& aMessage)
 	{
 	LOG_FUNC
-
 	TEirTag tag = static_cast<TEirTag>(aMessage.Int0());
 	LOG1(_L("CEirManSession::RegisterTag tag = %d"), tag);
 
-	if(!(tag >= EEirTagName && tag < EEirTagRESERVED))
-		{
-		__ASSERT_ALWAYS(EFalse, aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag));
-		}
-	else if(iEirTag != EEirTagRESERVED)
-		{
-		LOG1(_L("CEirManSession::RegisterTag ERROR, Tag in use: %d"), iEirTag);
-		aMessage.Complete(KErrInUse);
-		}
-	else
-		{
-		// Register this tag for callbacks
-		if(iEirManServer.EirFeatureState() == EEirFeatureReady)
-			{
-			// Eir is supported
-			TInt result = iEirManServer.EirManager().RegisterTag(tag, *this);
-			if(result == KErrNone)
-				{
-				iEirTag = tag;
-				}
-			aMessage.Complete(result);
-			}
-		else if(iEirManServer.EirFeatureState() == EEirFeaturePending)
-			{
-			// We don't know if eir is supported or not at this moment
-			iPendingEirTag = tag;
-			iRegisterMessage = aMessage;
-			}
-		else
-			{
-			// Eir is not supported
-			aMessage.Complete(KErrNotSupported);
-			}
-		}
+	iRegisterMessage = aMessage;
+	
+	iSession->RegisterTag(tag);
+
 	}
 
-void CEirManSession::DeregisterTag()
+void CEirManExternalSession::MesnRegisterComplete(TInt aResult)
 	{
-	LOG_FUNC
-	LOG1(_L("CEirManSession::DeregisterTag tag = %d"), iEirTag);
-	
-	if(iEirTag != EEirTagRESERVED)
+	if (aResult == KErrArgument)
 		{
-		// Deregister this tag for callbacks 
-		iEirManServer.EirManager().DeregisterTag(iEirTag);
-		iEirTag = EEirTagRESERVED;
+		__ASSERT_ALWAYS(EFalse, iRegisterMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag));
 		}
+	iRegisterMessage.Complete(aResult);
 	}
 
-// Eir Server has tried to register tag
-void CEirManSession::NotifyEirFeatureState(TInt aResult)
-	{
-	LOG1(_L("Eir Server has been notified feature ready, result: %d"), aResult);
-	if(aResult == KErrNone && !iRegisterMessage.IsNull())
-		{
-		__ASSERT_DEBUG(iEirManServer.EirFeatureState() == EEirFeatureReady, EIR_SESSION_PANIC(EEirSessionEirFeatureNotSupported));
-		TInt result = iEirManServer.EirManager().RegisterTag(iPendingEirTag, *this);
-		if(result == KErrNone)
-			{
-			iEirTag = iPendingEirTag;
-			}
-		iRegisterMessage.Complete(result);
-		}
-	else if(!iRegisterMessage.IsNull())
-		{
-		iRegisterMessage.Complete(aResult);
-		}
-	}
-
-TInt CEirManSession::RegisterSpaceAvailableListener(const RMessage2& aMessage, TBool& aComplete)
+TInt CEirManExternalSession::RegisterSpaceAvailableListener(const RMessage2& aMessage, TBool& aComplete)
 	{
 	LOG_FUNC
 
@@ -211,16 +297,16 @@
 	return KErrNone;
 	}
 	
-TInt CEirManSession::NewData(const RMessage2& aMessage)
+TInt CEirManExternalSession::NewData(const RMessage2& aMessage)
 	{
 	LOG_FUNC
-	__ASSERT_ALWAYS(iEirTag != EEirTagRESERVED, aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag));
+	__ASSERT_ALWAYS(iSession->EirTag() != EEirTagRESERVED, aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag));
 	TInt requiredLength = static_cast<TInt>(aMessage.Int0());
 
-	return iEirManServer.EirManager().NewData(iEirTag, requiredLength);
+	return iSession->NewData(requiredLength);
 	}
 
-TInt CEirManSession::CancelSpaceAvailableListener()
+TInt CEirManExternalSession::CancelSpaceAvailableListener()
 	{
 	LOG_FUNC
 
@@ -234,12 +320,12 @@
 	return KErrNone;
 	}
 
-TInt CEirManSession::SetData(const RMessage2& aMessage)
+TInt CEirManExternalSession::SetData(const RMessage2& aMessage)
 	{
 	LOG_FUNC
-	__ASSERT_ALWAYS(iEirTag != EEirTagRESERVED, aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag));
+	__ASSERT_ALWAYS(iSession->EirTag() != EEirTagRESERVED, aMessage.Panic(KEirManCliPncCat, EEirManPanicInvalidTag));
 	TEirDataMode eirDataMode = static_cast<TEirDataMode>(aMessage.Int1());
-	LOG2(_L("Tag: %d EirDataMode: %d"), iEirTag, eirDataMode);
+	LOG1(_L("EirDataMode: %d"),  eirDataMode);
 
 	// No need to allocate memory with an expensive malloc() call (via HBuf8::NewL or whatever), 
 	// since the EIR contents fit in the stack, and the EIR Manager will cache the data anyway
@@ -248,25 +334,13 @@
 	
 	if(err == KErrNone)
 		{
-		err = iEirManServer.EirManager().SetData(iEirTag, data, eirDataMode);
+		err = iSession->SetData(data, eirDataMode);
 		}
 	return err;
 	}
 
-// Callback from the EIR Manager
-void CEirManSession::MemnEirBlockAvailable(TEirTag aTag, TUint aSpaceForTag)
+void CEirManExternalSession::MesnSpaceAvailable(TUint aSpaceForTag)
 	{
-	LOG_FUNC
-	LOG2(_L("CEirManSession::MemnEirBlockAvailable Tag: %d space: %d"), aTag, aSpaceForTag);
-
-	// Silently discard callbacks not containing our EIR Tag
-	if(aTag != iEirTag)
-		{
-		__ASSERT_DEBUG(EFalse, EIR_SESSION_PANIC(EEirSessionInvalidEirTag));
-		LOG3(_L("CEirManSession::MemnEirBlockAvailable early return: aTag: %d iEirTag: %d space: %d"), aTag, iEirTag, aSpaceForTag);
-		return;
-		}
-
 	if(iDataAvailableListenerMessage.Handle())
 		{
 		LOG(_L("Listener outstanding, completing request"));
@@ -282,14 +356,92 @@
 		}
 	}
 
-void CEirManSession::CompleteSpaceAvailableRequest(TUint aBytesAvailable)
+void CEirManExternalSession::CompleteSpaceAvailableRequest(TUint aBytesAvailable)
 	{
 	LOG_FUNC
 	LOG1(_L("CEirManSession::CompleteSpaceAvailableRequest bytes: %d"), aBytesAvailable);
 	// Offer the space to the client
-	TPckg<TUint32> pckg(aBytesAvailable);
+	TPckgC<TUint32> pckg(aBytesAvailable);
 
 	TInt err = iDataAvailableListenerMessage.Write(0, pckg);
 	iDataAvailableListenerMessage.Complete(err);
 	}
 
+CEirManInternalSession* CEirManInternalSession::NewL(CEirManServer& aServer, MEirInternalSessionNotifier& aParent)
+	{
+	LOG_STATIC_FUNC
+	CEirManInternalSession* self = new(ELeave) CEirManInternalSession(aParent);
+	CleanupStack::PushL(self);
+	self->ConstructL(aServer);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CEirManInternalSession::CEirManInternalSession(MEirInternalSessionNotifier& aParent)
+	: iParent(aParent)
+	{
+	
+	}
+
+void CEirManInternalSession::ConstructL(CEirManServer& aServer)
+	{
+	iSession = CEirManSession::NewL(aServer, *this, ETrue);
+	iSetDataCb = new (ELeave) CAsyncCallBack(CActive::EPriorityHigh);
+	TCallBack cb(&SetDataCb, this);
+	iSetDataCb->Set(cb);
+	}
+
+CEirManInternalSession::~CEirManInternalSession()
+	{
+	delete iSetDataCb;
+	delete iSession;
+	}
+	
+void CEirManInternalSession::RegisterTag(TEirTag aTag)
+	{
+	iSession->RegisterTag(aTag);
+	}
+
+void CEirManInternalSession::SetData(const TDesC8& aData, TEirDataMode aMode)
+	{
+	delete iPendingData;
+	iPendingData = NULL;
+	iSetDataCb->Cancel();
+	iPendingData = aData.Alloc();
+	iPendingMode = aMode;
+	if (iPendingData)
+		{
+		iSetDataCb->CallBack();
+		}
+	}
+
+TInt CEirManInternalSession::SetDataCb(TAny* aThis)
+	{
+	static_cast<CEirManInternalSession*>(aThis)->DoSetData();
+	return KErrNone;
+	}
+
+void CEirManInternalSession::DoSetData()
+	{
+	TInt err = iSession->SetData(*iPendingData, iPendingMode);
+	if (err != KErrNone)
+		{
+		iParent.MeisnSetDataError(err);
+		}
+	}
+
+TInt CEirManInternalSession::NewData(TInt aRequiredLength)
+	{
+	return iSession->NewData(aRequiredLength);
+	}
+
+
+void CEirManInternalSession::MesnRegisterComplete(TInt aResult)
+	{
+	iParent.MeisnRegisterComplete(aResult);
+	}
+
+void CEirManInternalSession::MesnSpaceAvailable(TUint aSpaceForTag)
+	{
+	iParent.MeisnSpaceAvailable(aSpaceForTag - KEirLengthTagLength);
+	}