diff -r 000000000000 -r 29b1cd4cb562 bluetooth/btstack/eirman/eirmanserver.cpp --- /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 +#include +#include +#include +#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(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(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(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(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; + }