--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/eirman/eirmanserver.cpp Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,218 @@
+// 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:
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#include "eirmanserver.h"
+#include <e32base.h>
+#include <bluetooth/logger.h>
+#include <bluetooth/logger/components.h>
+#include <bluetooth/eirmanshared.h>
+#include "eirmansession.h"
+#include "eirmanager.h"
+#include "eirmanserversecuritypolicy.h"
+#include "linkmgr.h"
+#include "eirmanpanics.h"
+
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, LOG_COMPONENT_EIRMANAGER);
+#endif
+
+CEirManServer* CEirManServer::NewL(MHCICommandQueue& aCommandQueue, CLinkMgrProtocol& aLinkMgrProtocol)
+ {
+ LOG_STATIC_FUNC
+
+ CEirManServer* self = new(ELeave) CEirManServer(aCommandQueue, aLinkMgrProtocol);
+ CleanupStack::PushL(self);
+ // StartL is where the kernel checks that there isn't already an instance
+ // of the same server running, so do it before ConstructL.
+ self->StartL(KEirManServerName);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CEirManServer::~CEirManServer()
+ {
+ LOG_FUNC
+ delete iEirManager;
+ }
+
+CEirManServer::CEirManServer(MHCICommandQueue& aCommandQueue, CLinkMgrProtocol& aLinkMgrProtocol)
+ : CPolicyServer(CActive::EPriorityStandard, KEirManServerPolicy)
+ , iCommandQueue(aCommandQueue)
+ , iLinkMgrProtocol(aLinkMgrProtocol)
+ , iSessionCount(0)
+ , iIsFeaturesReady(EFalse)
+ , iIsEirSupported(EFalse)
+ {
+ LOG_FUNC
+ }
+
+void CEirManServer::ConstructL()
+ {
+ LOG_FUNC
+ }
+
+CSession2* CEirManServer::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const
+ {
+ LOG_FUNC
+ // Server will refuse to create any more session if we have found out eir isn't supported.
+ if(iIsFeaturesReady && !iIsEirSupported)
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+ LOG3(_L("CEirManServer::NewSessionL aVersion = (%d,%d,%d)"), aVersion.iMajor, aVersion.iMinor, aVersion.iBuild);
+
+ // Version number check...
+ TVersion v(KEirManSrvMajorVersionNumber,
+ KEirManSrvMinorVersionNumber,
+ KEirManSrvBuildVersionNumber);
+
+ if ( !User::QueryVersionSupported(v, aVersion) )
+ {
+ LEAVEIFERRORL(KErrNotSupported);
+ }
+
+ CEirManServer* ncThis = const_cast<CEirManServer*>(this);
+
+ CEirManSession* sess = CEirManSession::NewL(*ncThis);
+ LOG1(_L("\tsess = 0x%08x"), sess);
+ return sess;
+ }
+
+void CEirManServer::AddSession()
+ {
+ LOG_FUNC
+ if(iSessionCount++ == 0)
+ {
+ // While we have clients we need to make sure that the protocol remains alive.
+ iLinkMgrProtocol.LocalOpen();
+ }
+ }
+
+void CEirManServer::DropSession()
+ {
+ LOG_FUNC
+ if(--iSessionCount == 0)
+ {
+ // There are no long
+ iLinkMgrProtocol.LocalClose();
+ }
+ }
+
+void CEirManServer::NotifyFeaturesReady()
+ {
+ if(iIsFeaturesReady == EFalse)
+ {
+ __ASSERT_DEBUG(!iEirManager, EIR_SERVER_PANIC(EEirServerEirMangerAlreadyExists));
+ TRAPD(err, iEirManager = CEirManager::NewL(iCommandQueue, iLinkMgrProtocol));
+ iIsFeaturesReady = ETrue;
+
+ iSessionIter.SetToFirst();
+ CSession2* sessionPtr;
+ if(iLinkMgrProtocol.IsExtendedInquiryResponseSupportedLocally() && err == KErrNone)
+ {
+ iIsEirSupported = ETrue;
+ }
+ else
+ {
+ err = ((err != KErrNone) ? KErrNoMemory : KErrNotSupported);
+ }
+
+ while((sessionPtr = iSessionIter++) != NULL)
+ {
+ CEirManSession* eirSession = static_cast<CEirManSession*>(sessionPtr);
+ eirSession->NotifyEirFeatureState(err);
+ }
+ }
+ }
+
+TEirFeatureState CEirManServer::EirFeatureState()
+ {
+ TEirFeatureState ret = EEirFeaturePending;
+ if(iIsFeaturesReady && iIsEirSupported)
+ {
+ ret = EEirFeatureReady;
+ }
+ else if(iIsFeaturesReady && !iIsEirSupported)
+ {
+ ret = EEirFeatureNotSupported;
+ }
+ else
+ {
+ // ret will still be EEirFeaturePending
+ }
+ return ret;
+ }
+
+CPolicyServer::TCustomResult CEirManServer::CustomSecurityCheckL(const RMessage2& aMsg, TInt& /*aAction*/, TSecurityInfo& /*aMissing*/)
+ {
+ TEirManMessages function = static_cast<TEirManMessages>(aMsg.Function());
+ TEirTag tag;
+ TCustomResult result = EFail; //Fail everything by default
+ _LIT_SECURITY_POLICY_S0(KSDPSecurityPolicy, KSDPServerID);
+ _LIT_SECURITY_POLICY_S0(KStackSecurityPolicy, KStackID);
+ _LIT_SECURITY_POLICY_C1(KVendorSpecificDataSecurityPolicy, ECapabilityWriteDeviceData);
+ if(function == EEirManRegisterTag)
+ {
+ tag = static_cast<TEirTag>(aMsg.Int0());
+ switch(tag)
+ {
+ case EEirTagName:
+ case EEirTagTxPowerLevel:
+ /** These must have come from the stack **/
+ if(KStackSecurityPolicy.CheckPolicy(aMsg))
+ {
+ result = EPass;
+ }
+ break;
+ case EEirTagSdpUuid16:
+ case EEirTagSdpUuid32:
+ case EEirTagSdpUuid128:
+ /** These must have come from SDP server **/
+ if(KSDPSecurityPolicy.CheckPolicy(aMsg))
+ {
+ result = EPass;
+ }
+ break;
+ case EEirTagManufacturerSpecific:
+ /** To do this you must have write device data **/
+ if(KVendorSpecificDataSecurityPolicy.CheckPolicy(aMsg))
+ {
+ result = EPass;
+ }
+ break;
+
+ case EEirTagFlags:
+ /** At present no implementation of Flags is supported.
+ So we are rejecting this until an implementation is provided. **/
+ default: //unknown or reserved tag, reject
+ //no need to do anything
+ break;
+ }
+ }
+ //Anything not covered by the above is invalid so do nothing and let it fail
+ if(result == EFail)
+ {
+ LOG1(_L("CEirManServer::CustomSecurityCheckL failed. Function: %d"), function);
+ }
+ return result;
+ }