bluetooth/btstack/linkmgr/encryptionkeyrefreshhelper.cpp
branchRCL_3
changeset 25 99439b07e980
equal deleted inserted replaced
24:e9b924a62a66 25:99439b07e980
       
     1 // Copyright (c) 2010 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 the License "Symbian Foundation License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <bluetooth/logger.h>
       
    17 
       
    18 #include "encryptionkeyrefreshhelper.h"
       
    19 #include "hcifacade.h"
       
    20 #include "linkmgr.h"
       
    21 
       
    22 #ifdef __FLOG_ACTIVE
       
    23 _LIT8(KLogComponent, LOG_COMPONENT_LINKMGR);
       
    24 #endif
       
    25 
       
    26 CEncryptionKeyRefresher::CEncryptionKeyRefresher(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink)
       
    27 	: CPhysicalLinkHelper(aLinkMgr, aLink)
       
    28 	{
       
    29 	LOG_FUNC
       
    30 	}
       
    31 
       
    32 CEncryptionKeyRefresher* CEncryptionKeyRefresher::NewL(CPhysicalLinksManager& aLinkMgr, CPhysicalLink& aLink)
       
    33 	{
       
    34 	LOG_STATIC_FUNC
       
    35 	CEncryptionKeyRefresher* self = new(ELeave) CEncryptionKeyRefresher(aLinkMgr, aLink);
       
    36 	CleanupStack::PushL(self);
       
    37 	self->ConstructL();
       
    38 	CleanupStack::Pop(self);
       
    39 	return self;
       
    40 	}
       
    41 	
       
    42 void CEncryptionKeyRefresher::ConstructL()
       
    43 	{
       
    44 	LOG_FUNC
       
    45 	
       
    46 	BaseConstructL();
       
    47 	
       
    48 	iStateFactory = CEncryptionKeyRefresherStateFactory::NewL();
       
    49 	iState = &(iStateFactory->GetState(CEncryptionKeyRefresherStateFactory::EIdle));
       
    50 	}
       
    51 	
       
    52 CEncryptionKeyRefresher::~CEncryptionKeyRefresher()
       
    53 	{
       
    54 	LOG_FUNC
       
    55 	}
       
    56 
       
    57 void CEncryptionKeyRefresher::EncryptionKeyRefreshComplete(TInt aError)
       
    58 	{
       
    59 	LOG_FUNC
       
    60 	iState->EncryptionKeyRefreshComplete(*this, aError);
       
    61 	}
       
    62 
       
    63 void CEncryptionKeyRefresher::TimerExpired()
       
    64 	{
       
    65 	LOG_FUNC
       
    66 	iState->TimerExpired(*this);
       
    67 	}
       
    68 
       
    69 void CEncryptionKeyRefresher::HandleError( TInt aError)
       
    70 	{
       
    71 	LOG_FUNC
       
    72 	iState->Error(*this, aError);
       
    73 	}
       
    74 
       
    75 void CEncryptionKeyRefresher::StartHelper()
       
    76 	{
       
    77 	LOG_FUNC
       
    78 	iState->Start(*this);
       
    79 	}
       
    80 	
       
    81 void CEncryptionKeyRefresher::EventReceived(TBTBasebandEventNotification& aEvent)
       
    82 	{
       
    83 	LOG_FUNC
       
    84 	iState->EventReceived(*this, aEvent);
       
    85 	}
       
    86 		
       
    87 
       
    88 //----------------------------------------------------------------------------------
       
    89 // STATE FACTORY
       
    90 //----------------------------------------------------------------------------------
       
    91 
       
    92 CEncryptionKeyRefresherStateFactory* CEncryptionKeyRefresherStateFactory::NewL()
       
    93 	{
       
    94 	LOG_STATIC_FUNC
       
    95 	CEncryptionKeyRefresherStateFactory* ret=new (ELeave) CEncryptionKeyRefresherStateFactory();
       
    96 	CleanupStack::PushL(ret);
       
    97 	ret->ConstructL();
       
    98 	CleanupStack::Pop(ret);
       
    99 	return ret;
       
   100 	}
       
   101 
       
   102 void CEncryptionKeyRefresherStateFactory::ConstructL()
       
   103 	{
       
   104 	LOG_FUNC	
       
   105 	iStates[EIdle]					=new (ELeave) TEkrStateIdle(*this);
       
   106 	iStates[EDisablingLPM]			=new (ELeave) TEkrStateDisablingLPM(*this);
       
   107 	iStates[ERefreshingKey]			=new (ELeave) TEkrStateRefreshingKey(*this);
       
   108 	}
       
   109 
       
   110 CEncryptionKeyRefresherStateFactory::CEncryptionKeyRefresherStateFactory()
       
   111 	{
       
   112 	LOG_FUNC
       
   113 	iStates.DeleteAll();
       
   114 	}
       
   115 
       
   116 const TEncryptionKeyRefresherState& CEncryptionKeyRefresherStateFactory::GetState(CEncryptionKeyRefresherStateFactory::TEncryptionKeyRefresherStates aState) const
       
   117 	{
       
   118 	LOG_FUNC
       
   119 	__ASSERT_DEBUG(iStates[aState],  Panic(EEncryptionKeyRefresherInvalidState));
       
   120 	return *iStates[aState];
       
   121 	}
       
   122 
       
   123 TInt CEncryptionKeyRefresherStateFactory::StateIndex(const TEncryptionKeyRefresherState* aState) const
       
   124 	{
       
   125 	LOG_FUNC
       
   126 	TInt state;
       
   127 	for (state = 0; state < EEncryptionKeyRefresherMaxState; state++)
       
   128 		{
       
   129 		if (iStates[state] == aState)
       
   130 			{
       
   131 			return state;
       
   132 			}
       
   133 		}
       
   134 	
       
   135 	return KUnknownState;
       
   136 	}
       
   137 
       
   138 
       
   139 //----------------------------------------------------------------------------------
       
   140 // STATES
       
   141 //----------------------------------------------------------------------------------
       
   142 
       
   143 TEncryptionKeyRefresherState::TEncryptionKeyRefresherState(CEncryptionKeyRefresherStateFactory& aFactory)
       
   144 : iFactory(aFactory)
       
   145 	{
       
   146 	LOG_FUNC
       
   147 	}
       
   148 
       
   149 void TEncryptionKeyRefresherState::PanicInState(TLinkPanic aPanic) const
       
   150 	{
       
   151 	LOG_FUNC
       
   152 	Panic(aPanic, iFactory.StateIndex(this));
       
   153 	}
       
   154 
       
   155 void TEncryptionKeyRefresherState::ChangeState(CEncryptionKeyRefresher& aContext, CEncryptionKeyRefresherStateFactory::TEncryptionKeyRefresherStates aState) const
       
   156 	{
       
   157 	LOG_FUNC
       
   158 	
       
   159 	aContext.iState->Exit(aContext);
       
   160 
       
   161 #ifdef __FLOG_ACTIVE
       
   162 	const TEncryptionKeyRefresherState* state=&iFactory.GetState(aState);
       
   163 	LOG2(_L("EncryptionKeyRefresher: State %S -> %S"), &aContext.iState->iName, &state->iName);
       
   164 #endif //__FLOG_ACTIVE
       
   165 	aContext.iState=&iFactory.GetState(aState);
       
   166 
       
   167 	aContext.iState->Enter(aContext);
       
   168 	}
       
   169 
       
   170 void TEncryptionKeyRefresherState::Enter(CEncryptionKeyRefresher& /*aContext*/) const
       
   171 	{
       
   172 	LOG_FUNC
       
   173 	// do nothing
       
   174 	}
       
   175 
       
   176 void TEncryptionKeyRefresherState::Exit(CEncryptionKeyRefresher& /*aContext*/) const
       
   177 	{
       
   178 	LOG_FUNC
       
   179 	// do nothing
       
   180 	}
       
   181 
       
   182 void TEncryptionKeyRefresherState::Start(CEncryptionKeyRefresher& /*aContext*/) const
       
   183 	{
       
   184 	LOG_FUNC
       
   185 	PanicInState(EEncryptionKeyRefresherStateMachineInvalidEvent);
       
   186 	}
       
   187 
       
   188 void TEncryptionKeyRefresherState::Error(CEncryptionKeyRefresher& aContext, TInt /*aErr*/) const
       
   189 	{
       
   190 	LOG_FUNC
       
   191 	aContext.CancelNotify();
       
   192 	aContext.RemoveTimer();
       
   193 	ChangeState(aContext, CEncryptionKeyRefresherStateFactory::EIdle);
       
   194 	}
       
   195 
       
   196 void TEncryptionKeyRefresherState::EventReceived(CEncryptionKeyRefresher& /*aContext*/, TBTBasebandEventNotification& /*aEvent*/) const
       
   197 	{
       
   198 	LOG_FUNC
       
   199 	// do nothing
       
   200 	}
       
   201 
       
   202 void TEncryptionKeyRefresherState::TimerExpired(CEncryptionKeyRefresher& aContext) const
       
   203 	{
       
   204 	LOG_FUNC
       
   205 	aContext.CancelNotify();
       
   206 	ChangeState(aContext, CEncryptionKeyRefresherStateFactory::EIdle);
       
   207 	}
       
   208 
       
   209 void TEncryptionKeyRefresherState::EncryptionKeyRefreshComplete(CEncryptionKeyRefresher& /*aContext*/, TInt /*aError*/) const
       
   210 	{
       
   211 	LOG_FUNC
       
   212 	// do nothing
       
   213 	}
       
   214 
       
   215 //----------------------------------------------------------------------------------
       
   216 
       
   217 TEkrStateIdle::TEkrStateIdle(CEncryptionKeyRefresherStateFactory& aFactory)
       
   218 : TEncryptionKeyRefresherState(aFactory)
       
   219 	{
       
   220 	LOG_FUNC
       
   221 	STATENAME("TEkrStateIdle");
       
   222 	}
       
   223 
       
   224 void TEkrStateIdle::Start(CEncryptionKeyRefresher& aContext) const
       
   225 	{
       
   226 	LOG_FUNC
       
   227 	aContext.QueueTimer(KTimeoutEncryptionKeyRefresh);	// watchdog timer
       
   228 	ChangeState(aContext, CEncryptionKeyRefresherStateFactory::EDisablingLPM);
       
   229 	}	
       
   230 
       
   231 void TEkrStateIdle::Enter(CEncryptionKeyRefresher& aContext) const
       
   232 	{
       
   233 	LOG_FUNC
       
   234 	// async call to delete the helper
       
   235 	aContext.iLink.AsyncDeleteKeyRefresher();
       
   236 	}	
       
   237 
       
   238 //----------------------------------------------------------------------------------
       
   239 
       
   240 TEkrStateDisablingLPM::TEkrStateDisablingLPM(CEncryptionKeyRefresherStateFactory& aFactory)
       
   241 : TEncryptionKeyRefresherState(aFactory)
       
   242 	{
       
   243 	LOG_FUNC
       
   244 	STATENAME("TEkrStateDisablingLPM");
       
   245 	}
       
   246 
       
   247 void TEkrStateDisablingLPM::Enter(CEncryptionKeyRefresher& aContext) const
       
   248 	{
       
   249 	LOG_FUNC
       
   250 	
       
   251 	if (aContext.iLink.LinkMode() == EActiveMode)
       
   252 		{
       
   253 		// Skip straight on to refresh the key
       
   254 		ChangeState(aContext, CEncryptionKeyRefresherStateFactory::ERefreshingKey);
       
   255 		}
       
   256 	else
       
   257 		{
       
   258 		aContext.NotifyBasebandEvent(ENotifyActiveMode);
       
   259 		}
       
   260 	
       
   261 	// DisableLPM even if link is active to prevent possible LPM requests during key refresh
       
   262 	aContext.DisableLPM();
       
   263 	}
       
   264 
       
   265 void TEkrStateDisablingLPM::EventReceived(CEncryptionKeyRefresher& aContext, TBTBasebandEventNotification& aEvent) const
       
   266 	{
       
   267 	LOG_FUNC
       
   268 	if (aEvent.EventType()==ENotifyActiveMode && aEvent.ErrorCode()==KErrNone)
       
   269 		{
       
   270 		ChangeState(aContext, CEncryptionKeyRefresherStateFactory::ERefreshingKey);
       
   271 		}
       
   272 	else 
       
   273 		{
       
   274 		LOG(_L("CEncryptionKeyRefresher failed in DisableLPM"));
       
   275 		// If we can't put ourselves into active mode then don't bother with 
       
   276 		// refresh, it'll probably cause more problems than it would solve
       
   277 		// we can quit SM, don't need to rewind
       
   278 		ChangeState(aContext, CEncryptionKeyRefresherStateFactory::EIdle);
       
   279 		}
       
   280 	}
       
   281 
       
   282 //----------------------------------------------------------------------------------
       
   283 TEkrStateRefreshingKey::TEkrStateRefreshingKey(CEncryptionKeyRefresherStateFactory& aFactory)
       
   284 : TEncryptionKeyRefresherState(aFactory)
       
   285 	{
       
   286 	LOG_FUNC
       
   287 	STATENAME("TEkrStateRefreshingKey");
       
   288 	}
       
   289 
       
   290 void TEkrStateRefreshingKey::Enter(CEncryptionKeyRefresher& aContext) const
       
   291 	{
       
   292 	LOG_FUNC
       
   293 	
       
   294 	TRAPD(err, aContext.iLinkMgr.HCIFacade().RefreshEncryptionKeyL(aContext.iLink.Handle()));
       
   295 	
       
   296 	if(err)
       
   297 		{
       
   298 		ChangeState(aContext, CEncryptionKeyRefresherStateFactory::EIdle);
       
   299 		}
       
   300 	}
       
   301 
       
   302 void TEkrStateRefreshingKey::EncryptionKeyRefreshComplete(CEncryptionKeyRefresher& aContext, TInt __DEBUG_ONLY(aError)) const
       
   303 	{
       
   304 	LOG_FUNC
       
   305 	LOG1(_L("EncryptionKeyRefresh completed with error %d"), aError);
       
   306 
       
   307 	// Don't really care what the error is, this is just a best effort service
       
   308 	// anyway
       
   309 	ChangeState(aContext, CEncryptionKeyRefresherStateFactory::EIdle);
       
   310 	}
       
   311