bluetooth/btstack/l2cap/L2CapDebugControlInterface.cpp
changeset 0 29b1cd4cb562
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetooth/btstack/l2cap/L2CapDebugControlInterface.cpp	Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,507 @@
+// Copyright (c) 2003-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/logger.h>
+#include "L2CapDebugControlInterface.h"
+
+#include <bt_subscribe.h>
+#include "l2util.h"
+#include "BTSec.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, LOG_COMPONENT_L2CAP);
+#endif
+
+CDebugControlInterface::CDebugControlInterface()
+ : iSDUFlushQueuedSDUFlushed(0),
+   iSDUFlushPartialSentSDUFlushed(0),
+   iSDUFlushSentSDUFlushed(0),
+   iFlushedPDUMuxerResend(0),
+   iFlushedPDUDataFlowResend(0),
+   iFlushedPDUIFrame(0)
+	{
+	LOG_FUNC
+	for(TInt i=0;i<EMaxType;i++)
+		{
+		for(TInt j=0;j<EMaxAllocationType;j++)
+			{
+			iAllocations[i][j] = NULL;
+			}
+		}
+	DefinePublications();
+	}
+
+CDebugControlInterface::~CDebugControlInterface()
+	{
+	LOG_FUNC
+	DeletePublications();
+
+	iPDUTimerRecords.ResetAndDestroy();	
+	iPDUTimerRecords.Close();
+	iPDUGroupTimerRecords.ResetAndDestroy();
+	iPDUGroupTimerRecords.Close();
+	}
+	
+	
+/*static*/ CDebugControlInterface* CDebugControlInterface::NewL()
+	{
+	LOG_STATIC_FUNC
+	// This is done this way to allow future enhancement of this class.
+	CDebugControlInterface* self = new(ELeave) CDebugControlInterface();
+	return self;
+	}
+
+void CDebugControlInterface::DefinePublications()
+	{
+	LOG_FUNC
+
+//Capabilities don't really matter here because these
+//keys are only used in debug builds
+_LIT_SECURITY_POLICY_PASS(KPassPolicy);
+
+	for(TInt i=0;i<EMaxType;i++)
+		{
+		for(TInt j=0;j<EMaxAllocationType;j++)
+			{
+			(void)(iProperty.Define(KPropertyKeyBluetoothL2CapDebugBase + (i * 0x10) + j,
+									RProperty::EInt,
+									KPassPolicy,
+									KPassPolicy));
+			}
+		}
+	(void)(iProperty.Define(KPropertyKeyBluetoothL2DBGGetTimerGrpCID,
+							RProperty::EInt,
+							KPassPolicy,
+							KPassPolicy));
+
+	(void)(iProperty.Define(KPropertyKeyBluetoothL2DBGMinPDUGetTime,
+							RProperty::EInt,
+							KPassPolicy,
+							KPassPolicy));
+							
+	(void)(iProperty.Define(KPropertyKeyBluetoothL2DBGMaxPDUGetTime,
+							RProperty::EInt,
+							KPassPolicy,
+							KPassPolicy));
+
+	(void)(iProperty.Define(KPropertyKeyBluetoothL2DBGMinPDUSentTime,
+							RProperty::EInt,
+							KPassPolicy,
+							KPassPolicy));
+							
+	(void)(iProperty.Define(KPropertyKeyBluetoothL2DBGMaxPDUSentTime,
+							RProperty::EInt,
+							KPassPolicy,
+							KPassPolicy));
+
+	(void)(iProperty.Define(KPropertyKeyBluetoothL2DBGAvePDUGetTime,
+							RProperty::EInt,
+							KPassPolicy,
+							KPassPolicy));
+							
+	(void)(iProperty.Define(KPropertyKeyBluetoothL2DBGAvePDUSentTime,
+							RProperty::EInt,
+							KPassPolicy,
+							KPassPolicy));
+
+	(void)(iProperty.Define(KPropertyKeyBluetoothQueuedSDUFlushedCounter,
+							RProperty::EInt,
+							KPassPolicy,
+							KPassPolicy));
+							
+	(void)(iProperty.Define(KPropertyKeyBluetoothPartialSentSDUFlushedCounter,
+							RProperty::EInt,
+							KPassPolicy,
+							KPassPolicy));
+							
+	(void)(iProperty.Define(KPropertyKeyBluetoothSentSDUFlushedCounter,
+							RProperty::EInt,
+							KPassPolicy,
+							KPassPolicy));
+							
+	(void)(iProperty.Define(KPropertyKeyBluetoothFlushedPDUMuxerResend,
+							RProperty::EInt,
+							KPassPolicy,
+							KPassPolicy));
+							
+	(void)(iProperty.Define(KPropertyKeyBluetoothFlushedPDUDataFlowResend,
+							RProperty::EInt,
+							KPassPolicy,
+							KPassPolicy));
+							
+	(void)(iProperty.Define(KPropertyKeyBluetoothFlushedPDUIFrame,
+							RProperty::EInt,
+							KPassPolicy,
+							KPassPolicy));
+							
+	(void)(iProperty.Define(KPropertyKeyBluetoothIncompleteErroredSDUReceived,
+							RProperty::EInt,
+							KPassPolicy,
+							KPassPolicy));
+	}
+
+void CDebugControlInterface::DeletePublications()
+	{
+	LOG_FUNC
+	TSecureId thisSID = RProcess().SecureId();
+	
+	for(TInt i=0;i<EMaxType;i++)
+		{
+		for(TInt j=0;j<EMaxAllocationType;j++)
+			{
+			iProperty.Delete(thisSID, 
+			                 KPropertyKeyBluetoothL2CapDebugBase + (i * 0x10) + j);
+			}
+		}
+
+	iProperty.Delete(thisSID, KPropertyKeyBluetoothL2DBGGetTimerGrpCID);
+
+	iProperty.Delete(thisSID, KPropertyKeyBluetoothL2DBGMinPDUGetTime);
+	iProperty.Delete(thisSID, KPropertyKeyBluetoothL2DBGMaxPDUGetTime);
+
+	iProperty.Delete(thisSID, KPropertyKeyBluetoothL2DBGMinPDUSentTime);
+	iProperty.Delete(thisSID, KPropertyKeyBluetoothL2DBGMaxPDUSentTime);
+
+	iProperty.Delete(thisSID, KPropertyKeyBluetoothL2DBGAvePDUGetTime);
+	iProperty.Delete(thisSID, KPropertyKeyBluetoothL2DBGAvePDUSentTime);
+
+
+	iProperty.Delete(thisSID, KPropertyKeyBluetoothQueuedSDUFlushedCounter);
+	iProperty.Delete(thisSID, KPropertyKeyBluetoothPartialSentSDUFlushedCounter);
+	iProperty.Delete(thisSID, KPropertyKeyBluetoothSentSDUFlushedCounter);
+	iProperty.Delete(thisSID, KPropertyKeyBluetoothFlushedPDUMuxerResend);
+	iProperty.Delete(thisSID, KPropertyKeyBluetoothFlushedPDUDataFlowResend);
+	iProperty.Delete(thisSID, KPropertyKeyBluetoothFlushedPDUIFrame);
+	iProperty.Delete(thisSID, KPropertyKeyBluetoothIncompleteErroredSDUReceived);
+	}
+
+		
+// Debug Interface.
+void CDebugControlInterface::ObjectAllocation(TObjectType aObjectType, TAllocationType aAllocType)
+	{
+	LOG_FUNC
+	TSecureId thisSID = RProcess().SecureId();
+	
+	iAllocations[aObjectType][aAllocType]++;
+	(void)iProperty.Set(thisSID,
+						KPropertyKeyBluetoothL2CapDebugBase + (aObjectType * 0x10) + aAllocType,
+						iAllocations[aObjectType][aAllocType]);
+	
+	
+	if(aAllocType == EAllocated && 
+	                 (iAllocations[aObjectType][EAllocated] - iAllocations[aObjectType][EDeleted]) > iAllocations[aObjectType][EPeak])
+		{
+		iAllocations[aObjectType][EPeak] = static_cast<TUint16>(iAllocations[aObjectType][EAllocated] - iAllocations[aObjectType][EDeleted]);
+		(void)iProperty.Set(thisSID,
+							KPropertyKeyBluetoothL2CapDebugBase + (aObjectType * 0x10) + EPeak,
+							iAllocations[aObjectType][EPeak]);
+		}
+	}
+
+void CDebugControlInterface::PDUTimer(TPDUTimerEvent aEvent, TAny* aUID, TUint16 aGrpID)
+	{
+	LOG_FUNC
+	TPDUTimerRecord* rec = NULL;
+	TInt rerr = KErrNone;
+	
+	switch(aEvent)
+		{
+		case EBFrameCreated:
+			rec = new TPDUTimerRecord(aUID, aGrpID, TPDUTimerRecord::EPDUBFrameTimer);
+			if(rec)
+				{
+				rerr = iPDUTimerRecords.Append(rec);
+				}
+			else
+				{
+				rerr = KErrNoMemory;
+				}
+			break;				
+
+		case EIFrameCreated:
+			rec = new TPDUTimerRecord(aUID, aGrpID, TPDUTimerRecord::EPDUIFrameTimer);
+			if(rec)
+				{
+				rerr = iPDUTimerRecords.Append(rec);
+				}
+			else
+				{
+				rerr = KErrNoMemory;
+				}
+			break;				
+			
+		case EUnsegmentedFrameCreated:
+			rec = new TPDUTimerRecord(aUID, aGrpID, TPDUTimerRecord::EPDUUnsegmentedFrameTimer);
+			if(rec)
+				{
+				rerr = iPDUTimerRecords.Append(rec);
+				}
+			else
+				{
+				rerr = KErrNoMemory;
+				}
+			break;				
+
+		case EGetPDUCalled:
+			{
+			TIdentityRelation<TPDUTimerRecord> relation(UIDLinkMatch);
+			TPDUTimerRecord temp(aUID, 0, TPDUTimerRecord::TPDUTimerType(0));
+			TInt ix = iPDUTimerRecords.Find(&temp, relation);
+			if(ix != KErrNotFound)
+				{
+				iPDUTimerRecords[ix]->MarkGetPDUCalled();
+				}
+			else
+				{
+				rerr = KErrNotFound;
+				}
+			}
+			break;				
+
+		case EPDUSent:
+			{
+			TPDUTimerRecord* uidRec = NULL;
+			TIdentityRelation<TPDUTimerRecord> relation(UIDLinkMatch);
+			TPDUTimerRecord temp(aUID, 0, TPDUTimerRecord::TPDUTimerType(0));
+			TInt ix = iPDUTimerRecords.Find(&temp, relation);
+			if(ix != KErrNotFound)
+				{
+				uidRec = iPDUTimerRecords[ix];
+				uidRec->MarkPDUSent();
+
+				TIdentityRelation<TPDUGroupTimerRecord> relGroup(GroupLinkMatch);
+				TPDUGroupTimerRecord tempGrp(aGrpID, iProperty);
+				TInt grpIx = iPDUGroupTimerRecords.Find(&tempGrp, relGroup);
+				if(grpIx == KErrNotFound)
+					{					
+					TPDUGroupTimerRecord* grpRecord = new TPDUGroupTimerRecord(aGrpID, iProperty);
+					if(grpRecord)
+						{
+						rerr = iPDUGroupTimerRecords.Append(grpRecord);
+						grpIx = iPDUGroupTimerRecords.Count() - 1;
+						}
+					else
+						{
+						rerr = KErrNoMemory;
+						}
+					}
+				if(rerr == KErrNone)
+					{
+					iPDUGroupTimerRecords[grpIx]->UpdateGroup(uidRec->GetPDUTI(),
+														      uidRec->SentPDUTI());			
+					}
+
+				iPDUTimerRecords.Remove(ix);
+				delete uidRec;
+				}
+			else
+				{
+				rerr = KErrNotFound;
+				}
+			}
+			break;
+			
+		default:
+			Panic(EL2CAPUpdatePDUTimerDebugFailed);
+			break;
+		};
+	}
+
+void CDebugControlInterface::UpdateFlushCounters(TFlushCountersEvent aEvent)
+	{
+	LOG_FUNC
+	TSecureId thisSID = RProcess().SecureId();
+	
+	switch(aEvent)
+		{
+		case ESDUFlushQueuedSDUFlushed:
+			iSDUFlushQueuedSDUFlushed++;
+			(void)(iProperty.Set(thisSID,
+								 KPropertyKeyBluetoothQueuedSDUFlushedCounter,
+								 iSDUFlushQueuedSDUFlushed));
+			break;	
+
+		case ESDUFlushPartialSentSDUFlushed:
+			iSDUFlushPartialSentSDUFlushed++;
+			(void)(iProperty.Set(thisSID,
+								 KPropertyKeyBluetoothPartialSentSDUFlushedCounter,
+								 iSDUFlushPartialSentSDUFlushed));
+			break;	
+
+		case ESDUFlushSentSDUFlushed:
+			iSDUFlushSentSDUFlushed++;
+			(void)(iProperty.Set(thisSID,
+								 KPropertyKeyBluetoothSentSDUFlushedCounter,
+								 iSDUFlushSentSDUFlushed));
+			break;	
+
+		case EFlushedPDUMuxerResend:
+			iFlushedPDUMuxerResend++;
+			(void)(iProperty.Set(thisSID,
+								 KPropertyKeyBluetoothFlushedPDUMuxerResend,
+								 iFlushedPDUMuxerResend));
+			break;	
+
+		case EFlushedPDUDataFlowResend:
+			iFlushedPDUDataFlowResend++;
+			(void)(iProperty.Set(thisSID,
+								 KPropertyKeyBluetoothFlushedPDUDataFlowResend,
+								 iFlushedPDUDataFlowResend));
+			break;	
+
+		case EFlushedPDUIFrame:
+			iFlushedPDUIFrame++;
+			(void)(iProperty.Set(thisSID,
+								 KPropertyKeyBluetoothFlushedPDUIFrame,
+								 iFlushedPDUIFrame));
+			break;	
+
+		case EIncompleteErroredSDUReceived:
+			iIncompleteErroredSDUReceived++;
+			(void)(iProperty.Set(thisSID,
+								 KPropertyKeyBluetoothIncompleteErroredSDUReceived,
+								 iIncompleteErroredSDUReceived));
+			break;
+			
+		default:
+			Panic(EL2CAPInvalidDebugFlushCounterEvent);
+			break;	
+		};
+	}
+	
+		
+/*static*/ TBool CDebugControlInterface::UIDLinkMatch(const TPDUTimerRecord& aA, 
+                                                      const TPDUTimerRecord& aB)
+	{
+	LOG_STATIC_FUNC
+	return aA.GetUID() == aB.GetUID();
+	}
+
+/*static*/ TBool CDebugControlInterface::GroupLinkMatch(const TPDUGroupTimerRecord& aA, 
+                 	                                    const TPDUGroupTimerRecord& aB)
+	{
+	LOG_STATIC_FUNC
+	return aA.GetGroupID() == aB.GetGroupID();
+	}
+
+
+TPDUTimerRecord::TPDUTimerRecord(TAny* aUID, TUint16 aGroupID, TPDUTimerType aTimerType)
+ : iUID(aUID),
+   iGroupID(aGroupID),
+   iTimerType(aTimerType)
+	{
+	LOG_FUNC
+	iTime.HomeTime();
+	}
+	
+void TPDUTimerRecord::MarkGetPDUCalled()
+	{
+	LOG_FUNC
+	TTime temp;
+	temp.HomeTime();
+	iGetPDUTI = temp.MicroSecondsFrom(iTime);	
+	}
+	
+void TPDUTimerRecord::MarkPDUSent()
+	{
+	LOG_FUNC
+	TTime temp;
+	temp.HomeTime();
+	iSentPDUTI = temp.MicroSecondsFrom(iTime);		
+	}
+
+
+
+TPDUGroupTimerRecord::TPDUGroupTimerRecord(TUint16 aGroupID, RProperty& aProperty)
+ : iMinGetPDU(0),
+   iMinSentPDU(0),
+   iMaxGetPDU(0),
+   iMaxSentPDU(0),
+   iAveGetPDU(0),
+   iAveSentPDU(0),
+   iSampleSize(0),
+   iGroupID(aGroupID),
+   iProperty(aProperty)
+	{
+	LOG_FUNC
+	}
+
+void TPDUGroupTimerRecord::UpdateGroup(const TTimeIntervalMicroSeconds& aGetPDUTime,
+					 				   const TTimeIntervalMicroSeconds& aSentPDUTime)
+	{
+	LOG_FUNC
+	// Covert the arguments to ms intervals.
+	TInt newGetPDUTime = I64INT(aGetPDUTime.Int64()) / 1000;
+	TInt newSentPDUTime = I64INT(aSentPDUTime.Int64()) / 1000;
+
+	if(newGetPDUTime < iMinGetPDU || iSampleSize == 0)
+		{
+		iMinGetPDU = newGetPDUTime;
+		}
+	if(newGetPDUTime > iMaxGetPDU || iSampleSize == 0)
+		{
+		iMaxGetPDU = newGetPDUTime;
+		}
+
+	if(newSentPDUTime < iMinSentPDU || iSampleSize == 0)
+		{
+		iMinSentPDU = newSentPDUTime;
+		}
+	if(newSentPDUTime > iMaxSentPDU || iSampleSize == 0)
+		{
+		iMaxSentPDU = newSentPDUTime;
+		}
+
+	iAveGetPDU = ((iAveGetPDU * iSampleSize) + newGetPDUTime) / (iSampleSize + 1);
+	iAveSentPDU = ((iAveSentPDU * iSampleSize) + newSentPDUTime) / (iSampleSize + 1);
+	++iSampleSize;
+
+	TInt cid = 0;
+	TSecureId thisSID = RProcess().SecureId();
+	
+	if(iProperty.Get(thisSID,
+					 KPropertyKeyBluetoothL2DBGSetTimerGrpCID,
+					 cid) == KErrNone)
+		{
+		if(cid == iGroupID)
+			{
+			(void)iProperty.Set(thisSID,
+			                    KPropertyKeyBluetoothL2DBGGetTimerGrpCID,				
+								iGroupID);
+
+			(void)iProperty.Set(thisSID,
+			                    KPropertyKeyBluetoothL2DBGMinPDUGetTime,				
+								iMinGetPDU);
+			(void)iProperty.Set(thisSID,
+			                    KPropertyKeyBluetoothL2DBGMaxPDUGetTime,				
+								iMaxGetPDU);
+
+			(void)iProperty.Set(thisSID,
+			                    KPropertyKeyBluetoothL2DBGMinPDUSentTime,				
+								iMinSentPDU);
+			(void)iProperty.Set(thisSID,
+			                    KPropertyKeyBluetoothL2DBGMaxPDUSentTime,				
+								iMaxSentPDU);
+
+			(void)iProperty.Set(thisSID,
+			                    KPropertyKeyBluetoothL2DBGAvePDUGetTime,				
+								iAveGetPDU);
+			(void)iProperty.Set(thisSID,
+			                    KPropertyKeyBluetoothL2DBGAvePDUSentTime,				
+								iAveSentPDU);
+
+			}
+		}								
+	}