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