bluetoothmgmt/btmgr/eirclient/src/eirpublisher.cpp
changeset 0 29b1cd4cb562
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothmgmt/btmgr/eirclient/src/eirpublisher.cpp	Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,264 @@
+// Copyright (c) 2007-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:
+//
+
+#include <bluetooth/eirpublisher.h>
+#include <e32uid.h>
+#include <e32base.h>
+#include <bluetooth/eirclient.h>
+#include <bluetooth/eirmanshared.h>
+#include "eirmanclientlogger.h"
+
+
+void Panic(TBTEirPublisherPanic aPanic)
+	{
+	User::Panic(KBTEirPublisherPanic, aPanic);
+	}
+
+EXPORT_C CEirPublisher* CEirPublisher::NewL(TEirTag aEirTag, MEirPublisherNotifier& aNotifier)
+	{
+	LOG1(_L8("CEirPublisher::NewL creating publisher with tag %d"), aEirTag);
+	CEirPublisher* self = new(ELeave) CEirPublisher(aEirTag, aNotifier);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CEirPublisher::CEirPublisher(TEirTag aEirTag, MEirPublisherNotifier& aNotifier)
+	: CActive(CActive::EPriorityStandard)
+	, iEirTag(aEirTag)
+	, iNotifier(aNotifier)
+	, iPublishOutstanding(EFalse)
+	, iRequiredBytes(0)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CEirPublisher::~CEirPublisher()
+	{
+	LOG_FUNC
+	iEirMan.Close(); // this should handle everything!
+	Cancel();
+	delete iNotifierAo;
+	}
+
+void CEirPublisher::ConstructL()
+	{
+	LOG_FUNC
+	iNotifierAo = new(ELeave) CEirPublisherNotifier(*this);
+	iEirMan.Connect(iStatus);
+	iState = EConnecting;
+	SetActive();
+	}
+
+/**
+Notify server the required bytes from this client for the Extended Inquiry Response packet.
+@param aRequiredBytes for the required bytes from this client
+*/
+EXPORT_C void CEirPublisher::PublishData(TInt aRequiredBytes)
+	{
+	LOG_FUNC
+	__ASSERT_DEBUG(iState != EInvalid, Panic(EUnexpectedPublisherState));
+	if(iState == ENoConnection)
+		{
+		// If there is no connection to server currently, create one and indicate a request is outstanding.
+		iEirMan.Connect(iStatus);
+		iState = EConnecting;
+		iPublishOutstanding = ETrue;
+		iRequiredBytes = aRequiredBytes;
+		SetActive();
+		}
+	else if(iState != EIdle)
+		{
+		iPublishOutstanding = ETrue;
+		iRequiredBytes = aRequiredBytes;
+		}
+	else
+		{
+		iState = ENewData;
+		iEirMan.NewData(aRequiredBytes, iStatus);
+		SetActive();
+		}
+	}
+
+/**
+Send data and its type to server to update the Extended Inquiry Response packet.
+@param aData for the data to be added into Extended Inquiry Response
+@param aDataMode for the type of data from this client (partial or complete)
+*/
+EXPORT_C void CEirPublisher::SetData(const TDesC8& aData, TEirDataMode aDataMode)
+	{
+	LOG_FUNC
+	// Make sure that client has an invitation to the party
+	__ASSERT_ALWAYS(iState == EDataCallback, PANIC(KEirManCliPncCat, EEirManPanicSetDataUninvited));
+	iState = ESettingData;
+	iEirMan.SetData(aData, aDataMode, iStatus);
+	SetActive();
+	}
+
+void CEirPublisher::RunL()
+	{
+	LOG_FUNC
+	LEAVEIFERRORL(iStatus.Int());
+	
+	switch(iState)
+		{
+	case EConnecting:
+		iEirMan.RegisterTag(iEirTag, iStatus);
+		iState = ERegisterTag;
+		SetActive();
+		break;
+	case ERegisterTag:
+		iNotifierAo->Start();
+		// Fall through...
+	case ENewData:
+		// Fall through...
+	case ESettingData:
+		if(iPublishOutstanding)
+			{
+			iPublishOutstanding = EFalse;
+			iState = ENewData;
+			iEirMan.NewData(iRequiredBytes, iStatus);
+			SetActive();
+			}
+		else if(iCallbackOutstanding)
+			{
+			iCallbackOutstanding = EFalse;
+			iState = EDataCallback;
+			LOG1(_L8("CEirPublisher::RunL: About to call back client with bytes available: %d"), iAvailableBytes);
+			iNotifier.MepnSpaceAvailable(iAvailableBytes);
+			}
+		else
+			{
+			iState = EIdle;
+			}
+		break;		
+	default:
+		// Unexpected
+		__ASSERT_DEBUG(EFalse, Panic(EUnexpectedPublisherState));
+		break;
+		}
+	}
+
+void CEirPublisher::DoCancel()
+	{
+	LOG_FUNC
+	iNotifierAo->Cancel();
+	// Because of asynchronous shutdown - we close the session and tidy up
+	// the active objects locally.
+	__ASSERT_DEBUG(!iEirMan.Handle(), Panic(EInvalidEirManHandle)); 
+	TRequestStatus* status = &iStatus;
+	User::RequestComplete(status, KErrCancel);
+	iState = EInvalid;
+	}
+
+TInt CEirPublisher::RunError(TInt aError)
+	{
+	LOG_FUNC
+	LOG1(_L8("CEirPublisher::RunError: %d"), aError);
+	// report error to client
+	iNotifier.MepnSetDataError(aError);
+	if (iState == EConnecting)
+		{
+		// We have a problem on Connecting to server, set the state to No Connection
+		iState = ENoConnection;
+		}
+	return KErrNone;
+	}
+
+void CEirPublisher::SpaceAvailable(TUint aSpace)
+	{
+	LOG_FUNC
+	
+	if (aSpace > KEirLengthTagLength)
+		{
+		iAvailableBytes = aSpace - KEirLengthTagLength;
+		}
+	else
+		{
+		iAvailableBytes = 0;
+		}
+	if(iState == EIdle)
+		{
+		iState = EDataCallback;
+		LOG1(_L8("CEirPublisher::RunL: About to call back client with bytes available: %d"), iAvailableBytes);
+		iNotifier.MepnSpaceAvailable(iAvailableBytes);
+		}
+	else
+		{
+		iCallbackOutstanding = ETrue;
+		}
+	}
+
+void CEirPublisher::NotifierError(TInt aError)
+	{
+	static_cast<void>(RunError(aError));
+	}
+
+REirMan& CEirPublisher::EirMan()
+	{
+	LOG_FUNC
+	return iEirMan;
+	}
+
+
+
+CEirPublisherNotifier::CEirPublisherNotifier(CEirPublisher& aPublisher)
+	: CActive(EPriorityStandard)
+	, iPublisher(aPublisher)
+	{
+	LOG_FUNC
+	CActiveScheduler::Add(this);
+	}
+
+CEirPublisherNotifier::~CEirPublisherNotifier()
+	{
+	LOG_FUNC
+	Cancel();
+	}
+
+void CEirPublisherNotifier::Start()
+	{
+	LOG_FUNC
+	iPublisher.EirMan().SpaceAvailableNotification(iSpaceAvailable, iStatus);
+	SetActive();
+	}
+
+void CEirPublisherNotifier::RunL()
+	{
+	LOG_FUNC
+	LEAVEIFERRORL(iStatus.Int());
+	TUint spaceAvailable = iSpaceAvailable;
+	iPublisher.EirMan().SpaceAvailableNotification(iSpaceAvailable, iStatus);
+	SetActive();
+	iPublisher.SpaceAvailable(spaceAvailable);
+	}
+
+void CEirPublisherNotifier::DoCancel()
+	{
+	LOG_FUNC
+	// Because of asynchronous shutdown - we close the session and tidy up
+	// the active objects locally.
+	__ASSERT_DEBUG(!(iPublisher.EirMan().Handle()), Panic(EInvalidEirManHandle)); 
+	TRequestStatus* status = &iStatus;
+	User::RequestComplete(status, KErrCancel);
+	}
+
+TInt CEirPublisherNotifier::RunError(TInt aError)
+	{
+	LOG_FUNC
+	iPublisher.NotifierError(aError);
+	return KErrNone;
+	}