bluetooth/btstack/linkmgr/hostresolver.h
changeset 0 29b1cd4cb562
child 23 5b153be919d4
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 1999-2009 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 "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // L2CAP Host resolver.
       
    15 // Implements Inquiry and Name lookup
       
    16 // 
       
    17 //
       
    18 
       
    19 #ifndef L2HOSTRESOLVER_H
       
    20 #define L2HOSTRESOLVER_H
       
    21 
       
    22 
       
    23 #include <bt_sock.h>
       
    24 #include <es_prot.h>
       
    25 #include <bluetooth/hcicommandqueue.h>
       
    26 #include <bluetooth/hcicommandqueueclient.h>
       
    27 
       
    28 // BT1.1: Could make these runtime configurable.
       
    29 
       
    30 // HCI Inquiry length time, in 1.28 seconds.
       
    31 static const TInt KInquiryLength		= 10;
       
    32 // Upper limit to number of results we can handle
       
    33 static const TInt KInquiryMaxResults	= 00;
       
    34 
       
    35 // Seconds between flushes
       
    36 static const TInt KFlushTimeoutSecs	= 5;
       
    37 // Number of flushes required to actually clear a record
       
    38 static const TInt KRecordDeathAge		= 120;	// 10 mins
       
    39 
       
    40 
       
    41 // Maximum flushes before the a device disappears to inquires
       
    42 static const TInt KRecordStaleAge		= 10; // 50 secs
       
    43 // Maximum flushes before the cache is set to stale (needing refresh)
       
    44 static const TInt KCacheStaleAge		= -1; // -1 == always needs refresh
       
    45 
       
    46 // While doing inquiry, set of watchdog every second
       
    47 static const TInt KInquiryWatchdogPeriod = 1;
       
    48 // Immidiately fetch the first 3 names
       
    49 static const TInt KImmediateNameFetch = 3;
       
    50 
       
    51 // Page Timeout for name request, we'll initially use this for each one
       
    52 static const TUint16 KMinNamePageTimeout = 0x1200; // 0x1200 = 3 secs
       
    53 // Amount to increase pagetimeout, everytime a lookup fails
       
    54 static const TUint16 KNamePageTimeoutIncrement = 0x140; // 0x140 = .2 sec
       
    55 /** Max Page Timeout for name request, we'll consider using (ACL connects
       
    56 are blocked while doing name lookup, so mustn't be too high!) **/
       
    57 static const TUint16 KMaxNamePageTimeout = 0x2500; // 0x2500 = 6 secs
       
    58 
       
    59 // Max times we'll try to get a single name while an inquiry pending
       
    60 static const TInt KMaxNameLookupAttemptsDuringInquiry = 1;
       
    61 // Max number of times to try to get a name
       
    62 static const TInt KMaxNameLookupAttempts = 4;
       
    63 
       
    64 
       
    65 
       
    66 class CBTInquiryMgr;
       
    67 class CBTInqResultRef;
       
    68 class CLinkMgrProtocol;
       
    69 
       
    70 
       
    71 enum TBTInqResultValid
       
    72 	{
       
    73 	EBluetoothAddr 					= 0x001, //000000000001
       
    74 	EBluetoothCoD		 			= 0x008, //000000001000
       
    75 	EBluetoothPageScanRepMode		= 0x080, //000010000000
       
    76 	EBluetoothPageScanMode          = 0x100, //000100000000
       
    77 	EBluetoothClockOffSet			= 0x200, //001000000000
       
    78 	EBluetoothRssi					= 0x400, //010000000000
       
    79 	EBluetoothEir					= 0x800, //100000000000
       
    80 	EBluetoothJuice			 =  EBluetoothCoD | 
       
    81 								EBluetoothPageScanRepMode | 
       
    82 								EBluetoothPageScanMode | 
       
    83 								EBluetoothClockOffSet
       
    84 	};
       
    85 
       
    86 
       
    87 /**
       
    88 	BT Inquiry Result record.
       
    89 	Ref counted object, deletes itself when no more CBTInqResultRef objects
       
    90 	point to it. Aggregates the TInquiryLogEntry type.
       
    91 **/
       
    92 
       
    93 NONSHARABLE_CLASS(CBTInqResultRecord) : public CBase
       
    94 	{
       
    95 friend class CBTInquiryMgr;
       
    96 friend class CBTInqResultRef;
       
    97 
       
    98 public:
       
    99 	TInquiryLogEntry& LogEntry();
       
   100 	void SetName(const TDesC8& aName);
       
   101 	const TDesC8& Name() const;
       
   102 	TBool IsNameRequestPending() const;
       
   103 	void SetNamePending(TBool aBool);
       
   104 	TBool IsNameRefreshRequested() const;
       
   105 	void SetNameRefreshRequested(TBool aBool);
       
   106 	TBool IsNameComplete() const;
       
   107 	void SetNameComplete(TBool aBool);
       
   108 	TBool IsExplicitNameRequest() const;
       
   109 	void SetExplicitNameRequest(TBool aBool);
       
   110 	TBool IsNameValid() const;
       
   111 	void SetNameValid(TBool aBool);
       
   112 	void SetNameLookupResultCode(TInt aResultCode);
       
   113 	TBool HaveNameLookupResult() const;
       
   114 	TInt NameLookupResultCode() const;
       
   115 	TInt NameLookupAttempts() const;
       
   116 	TInt IncFlushes();
       
   117 	void GetInquirySockAddr(TInquirySockAddr& aAddr);
       
   118 	TInt GetEir(TNameRecord& aNameRec, TBool aIgnoreCachedName);
       
   119 	TInt GetName(TNameRecord& aNameRec);
       
   120 	TInt AddIAC(TUint aIAC);
       
   121 	TBool HasRespondedToIAC(TUint aIAC);
       
   122 	TInt NumberOfIACsRespondedTo();
       
   123 	void ClearIACs();
       
   124 	inline TBool IsJuiceFromHCI() { return (EBluetoothJuice == (iJuiceFromHCIMask & EBluetoothJuice)); };//for the moment demand all
       
   125 	inline TBool IsPageScanModeFromHCI() { return iJuiceFromHCIMask & EBluetoothPageScanMode; };
       
   126 	inline TBool IsPageScanRepModeFromHCI() { return iJuiceFromHCIMask & EBluetoothPageScanRepMode; };
       
   127 	inline TBool IsCoDFromHCI() { return iJuiceFromHCIMask & EBluetoothCoD; };
       
   128 	inline TBool IsClockOffsetFromHCI() { return iJuiceFromHCIMask & EBluetoothClockOffSet; }
       
   129 	inline TBool IsEirPresent() { return iJuiceFromHCIMask & EBluetoothEir; }
       
   130 	inline TExtendedInquiryResponseDataCodec& Codec() { return iCodec; }
       
   131 	
       
   132 private:
       
   133 	enum TNameStatus
       
   134 		{
       
   135 		ENamePending = 1,
       
   136 		ENameRefreshRequested = 2,
       
   137 		ENameComplete = 4,
       
   138 		ENameExplicitRequest = 8, // An explicit name lookup has been requested, so don't put this to the back of the queue
       
   139 		};
       
   140 
       
   141 	~CBTInqResultRecord();
       
   142 	// Interface for CBTInquiryMgr
       
   143 	CBTInqResultRecord(const TBTDevAddr& aAddr);
       
   144 	// Interface for CBTInqResultRef
       
   145 	void Open();
       
   146 	void Close();
       
   147 
       
   148 	// Number of CBTInqResultRef objects pointing to this result
       
   149 	TInt				iRefCount;
       
   150 	// The actual inquiry log entry. It contains EIR data, RSSI value and old style TInquiryLogEntry.
       
   151 	TInquiryLogEntryWithEir	iEntry;
       
   152 	// The device name's state
       
   153 	TInt				iNameStatus; //Bit flag
       
   154 	// The result of name lookup, of >0 if one hasn't been done
       
   155 	TInt				iNameLookupResultCode;
       
   156 	// The device's name (if known), it can be from EIR or a Remote Name Request
       
   157 	TBuf8<KHCIRemoteDeviceNameMaxLength>	iName;
       
   158 	// Number of attempts made at getting name.
       
   159 	TInt				iNameLookupAttempts;
       
   160 	// Flush cycles since last seen (lower == newer).
       
   161 	TInt				iFlushes;
       
   162 	// IACs this device has responded to
       
   163 	RArray<TUint>		iIACs;
       
   164 	// Has inquiry log entry been populated by inquiry?
       
   165 	TUint16				iJuiceFromHCIMask;
       
   166 	// Has this entry been found during the current, ongoing inquiry?
       
   167 	TBool				iFoundDuringCurrentInquiry;
       
   168 	
       
   169 	TExtendedInquiryResponseDataCodec iCodec;
       
   170 	};
       
   171 
       
   172 /**
       
   173 	Inquiry result reference.
       
   174 	References a CBTInqResultRecord.
       
   175 **/
       
   176 NONSHARABLE_CLASS(CBTInqResultRef) : public CBase
       
   177 	{
       
   178 public:
       
   179 	CBTInqResultRef(CBTInqResultRef& aRef);
       
   180 	CBTInqResultRef(CBTInqResultRecord& aRec);
       
   181 	~CBTInqResultRef();
       
   182 	CBTInqResultRecord& Result() const;
       
   183 
       
   184 private:
       
   185 	// The pointer to actual CBTInqResultRecord
       
   186 	CBTInqResultRecord& iRecord;
       
   187 public:
       
   188 	// List to go on a view, in CBTInqResultSet
       
   189 	TDblQueLink			iLink;
       
   190 	};
       
   191 
       
   192 /**
       
   193 	BT Inquiry Result Set.
       
   194 	A view onto a set of the current inquiry results.
       
   195 **/
       
   196 NONSHARABLE_CLASS(CBTInqResultSet) : public CBase
       
   197 	{
       
   198 public:
       
   199 	CBTInqResultSet();
       
   200 	~CBTInqResultSet();
       
   201 	void Reset();
       
   202 	CBTInqResultRef* Add(CBTInqResultRecord& aRec);
       
   203 	CBTInqResultRef* FindEntry(const TBTDevAddr& aAddr);
       
   204 	CBTInqResultRef* NextResult();
       
   205 	CBTInqResultRef* CurrentResult();
       
   206 	void ReturnToFirstResult();
       
   207 	TBool IsEmpty();
       
   208 	void MoveToback(CBTInqResultRef& aRef);
       
   209 private:
       
   210 	typedef TDblQue<CBTInqResultRef> TResultRefQue;
       
   211 	typedef TDblQueIter<CBTInqResultRef> TResultQueIter;
       
   212 	TResultRefQue	iResultRefs;
       
   213 	TResultQueIter	iNextRefIter;
       
   214 	CBTInqResultRef* iCurrentResult;
       
   215 	};
       
   216 
       
   217 NONSHARABLE_STRUCT(TInquiryCacheAge)
       
   218 	{
       
   219 public:
       
   220 	TUint iIAC;
       
   221 	TInt iCacheAge;
       
   222 	};
       
   223 
       
   224 /**
       
   225 	BT Host resolver.
       
   226 	Represents one client host resolver session.
       
   227 	Only implements GetByAddress, as this is all the
       
   228 	BT API supports.
       
   229 **/
       
   230 NONSHARABLE_CLASS(CBTHostResolver) : public CHostResolvProvdBase
       
   231 	{
       
   232 public:
       
   233 	enum TInquiryStatus
       
   234 		{
       
   235 		EInquiryReady,
       
   236 		EInquiring,
       
   237 		EInquiryComplete
       
   238 		};
       
   239 	enum TNameLookupMode
       
   240 		{
       
   241 		EDontGetNames,
       
   242 		EDoGetNames
       
   243 		};
       
   244 	
       
   245 	enum TRequestState
       
   246 		{
       
   247 		EIdle,
       
   248 		EInquiry,
       
   249 		ENameLookup,
       
   250 		ESetLocalName,
       
   251 		EGetLocalName, 
       
   252 		EError	// LC added
       
   253 		};
       
   254 
       
   255 	CBTHostResolver(CBTInquiryMgr& aInquiryMgr);
       
   256 	~CBTHostResolver();
       
   257 	// From CHostResolvProvdBase
       
   258 	void GetByName(TNameRecord& aName);
       
   259 	void GetByAddress(TNameRecord& aName);
       
   260 	void SetHostName(TDes& aNameBuf);
       
   261 	void GetHostName(TDes& aNameBuf);
       
   262 // Need this to allow instantiation.  Doesn't seem to be callable though!
       
   263 // Simply stub it, as we don't actually care...
       
   264 	virtual TInt SetOption(TUint aLevel, TUint aName, const TDesC8& aOption);
       
   265 
       
   266 	// From CResolverProvdBase
       
   267 	void CancelCurrentOperation();
       
   268 
       
   269 	// IquiryMgr interface
       
   270 	void InquiryResult(CBTInqResultRecord& aResult);
       
   271 	void NameLookupResult(TInt aErr, const TBTDevAddr& aAddr, const TDesC8& aName);
       
   272 	void InquiryComplete(TInt aErr);
       
   273 	void SetLocalNameComplete(TInt aErr);
       
   274 	void GetLocalNameComplete(TInt aErr, const TDesC8& aName);
       
   275 
       
   276 	TUint GetIAC() const;
       
   277 	inline static TInt LinkOffset() {return _FOFF(CBTHostResolver, iLink);}
       
   278 
       
   279 	//From CResolverProvdBase
       
   280 	TInt SecurityCheck(MProvdSecurityChecker *aSecurityChecker);
       
   281 private:
       
   282 	void TryToCompleteRequest();
       
   283 	void CompleteRequest(TInt aErr);
       
   284 	void CompleteCurrentOperation();
       
   285 
       
   286 	CBTInquiryMgr&		iInquiryMgr;
       
   287 	// The record we're currently retreiving
       
   288 	TNameRecord*		iNameRecord;
       
   289 	// the buffer we get host name into
       
   290 	TDes*				iHostNameBuf;
       
   291 	
       
   292 	// Current user request.
       
   293 	TRequestState		iRequestState;
       
   294 	// Status of the on-going inquiry process
       
   295 	TInquiryStatus		iInquiryStatus;
       
   296 	// Get names or not?
       
   297 	TNameLookupMode		iNameLookupMode;
       
   298 	// Error code... Only valid when iInquiryStatus == EInquiryComplete
       
   299 	TInt				iInqCompletionCode;
       
   300 	// Set of devices found, to be returned to client
       
   301 	CBTInqResultSet		iResults;
       
   302 	// Member of Q in InquiryMgr.
       
   303 	TDblQueLink iLink;
       
   304 	//Mixin providing security checking, This is not an owned variable.
       
   305 	MProvdSecurityChecker* iSecurityChecker;
       
   306 	};
       
   307 
       
   308 #ifdef CONNECTION_PREEMPTS_INQUIRY
       
   309 class CConnectingStatusSubscriber;
       
   310 #endif
       
   311 
       
   312 /**
       
   313 	BT Inquiry Manager.
       
   314 	Singleton object that manages host resolvers, inquiries, and
       
   315 	name lookups.
       
   316 **/
       
   317 NONSHARABLE_CLASS(CBTInquiryMgr) : public CBase, public MHCICommandQueueClient
       
   318 	{
       
   319 public:
       
   320 	// Interface for CL2CAPProtocol
       
   321 	~CBTInquiryMgr();
       
   322 	static CBTInquiryMgr* NewL(CLinkMgrProtocol& aProtocol);
       
   323 	CBTHostResolver* NewHostResolverL();
       
   324 
       
   325 	void SetHCICommandQueue(MHCICommandQueue& aCommandQueue);
       
   326 	void ClearHCICommandQueue();
       
   327 
       
   328 	void ClockOffsetResult(const TBTDevAddr& aAddr, TBasebandTime aClockOffset);
       
   329 	void CoDResult(const TBTDevAddr& aConn, TUint aCoD);
       
   330 
       
   331 	void SetLocalNameComplete(TInt aErr);
       
   332 	void GetLocalNameComplete(TInt aErr, const TDesC8& aName);
       
   333 	void Suspend();
       
   334 	void Resume();
       
   335 	void SetInquiryMode();
       
   336 	
       
   337 
       
   338 #ifdef _DEBUG
       
   339 	void IncrementHRCount() {++iNumHRs;};
       
   340 	void DecrementHRCount() {--iNumHRs;};
       
   341 #endif
       
   342 
       
   343 	// Interface for CBTHostResolver
       
   344 	void StartInquiry(CBTHostResolver& aResolver, TUint aIAC, TBool aIgnoreCache);
       
   345 	void LookupName(CBTHostResolver& aResolver, const TBTDevAddr& aAddr, TBool aIgnoreCache, TBool aExplicitNameRequest);
       
   346 	void ClearCache();
       
   347 	TInt SetLocalName(const TDesC8& aName);
       
   348 	TInt GetLocalName();
       
   349 	CBTInqResultRef* FindExistingCacheEntry(const TBTDevAddr& aAddr);
       
   350 	CBTInqResultRef* AddEntryToCache(const TBTDevAddr& aAddr);
       
   351 	CBTInqResultRef* AddEntryWithJuiceToCache(const TInquiryLogEntry& aEntry);
       
   352 	CBTInqResultRef* AddEntryWithCoDToCache(const TBTDevAddr& aAddr, const TUint aCoD);
       
   353 	CBTInqResultRef* AddEntryWithClockOffsetToCache(const TBTDevAddr& aAddr, const TBasebandTime aClockOffset);
       
   354 	const TDesC8* DeviceNameFromCache(const TBTDevAddr& aAddr);
       
   355 	CBTInqResultRecord* BasebandParametersFromCache(const TBTDevAddr& aAddr);
       
   356 	void DeletingHostResolver();
       
   357 
       
   358 		enum THWState
       
   359 		{
       
   360 		EIdle = 0,
       
   361 		EInquiry,
       
   362 		ENameLookup,
       
   363 		EConnecting,	// can't do anything really!
       
   364 //		EConnected		// can't do anything ?
       
   365 		EOff,
       
   366 		ECancellingForNewIAC,
       
   367 		};
       
   368 
       
   369 	THWState HWState(){ return iHWState; }
       
   370 	void SetHWState(THWState aState);
       
   371 	void PublishStatus();
       
   372 
       
   373 	void CompleteCommands(TInt aErr);
       
   374 	TBool IsExtendedInquiryResponseSupported();
       
   375 
       
   376 	// commands sent to the controller -- called from external classes
       
   377 	void ReadRemoteNameL(const TBTDevAddr& aAddr);
       
   378 
       
   379 private: // Handling logical inquiry events
       
   380 	void WriteInquiryModeComplete(TBool aSucceeded);
       
   381 	void InquiryResult(TInt aErr,const TInquiryLogEntry& aEntry);
       
   382 	void InquiryComplete(TInt aErr, TUint8 aNumResponses);
       
   383 	void RemoteNameResult(TInt aErr, const TBTDevAddr& aAddr, const TBTDeviceName8& aBuf);
       
   384 	void RemoteHostSupportedFeatures(TInt aErr, const TBTDevAddr& aAddr, const TUint64& aHostSupportedFeatures);
       
   385 
       
   386 private: // from MHCICommandQueueClient
       
   387 	virtual void MhcqcCommandEventReceived(const THCIEventBase& aEvent, const CHCICommandBase* aRelatedCommand);
       
   388 	virtual void MhcqcCommandErrored(TInt aErrorCode, const CHCICommandBase* aCommand);
       
   389 
       
   390 private: // HCI event handling functions
       
   391 	// basic types
       
   392 	void CommandCompleteEvent(const THCIEventBase& aEvent);
       
   393 	void CommandStatusEvent(const THCIEventBase& aEvent, const CHCICommandBase& aCommand);
       
   394 
       
   395 	// first class events
       
   396 	void InquiryResultEvent(const THCIEventBase& aEvent);
       
   397 	void InquiryResultWithRSSIEvent(const THCIEventBase& aEvent);
       
   398 	void ExtendedInquiryResultEvent(const THCIEventBase& aEvent);
       
   399 	void InquiryCompleteEvent(const THCIEventBase& aEvent);
       
   400 	void RemoteNameReqCompleteEvent(const THCIEventBase& aEvent);
       
   401 	void RemoteHostSupportedFeaturesNotificationEvent(const THCIEventBase& aEvent);
       
   402 
       
   403 	// command complete events
       
   404 	void WriteInquiryModeOpcode(THCIErrorCode aHciErr, const THCIEventBase& aEvent);
       
   405 	void ReadLocalNameOpcode(THCIErrorCode aHciErr, const THCIEventBase& aEvent);
       
   406 	void InquiryCancelOpcode(THCIErrorCode aHciErr, const THCIEventBase& aEvent);
       
   407 
       
   408 private:
       
   409 	CBTInquiryMgr(CLinkMgrProtocol& aProtocol);
       
   410 	void ConstructL();
       
   411 
       
   412 	MHCICommandQueue& CommandQueue() const;
       
   413 
       
   414 	// commands sent to the controller
       
   415 	void CancelInquiryL();
       
   416 	void CancelRemoteNameL(const TBTDevAddr& aAddr);
       
   417 	void StartInquiryL(TUint aIAC, TUint8 aLength, TUint8 aNumResponses);
       
   418 	void WriteInquiryModeL(TUint8 aInquiryMode);
       
   419 	void LookupNameL(const TInquiryLogEntry& aEntry);
       
   420 	void ReadLocalNameL();
       
   421 
       
   422 	void DoInquiry();
       
   423 	void DoNameLookup(TBool aInquiryComplete);
       
   424 	void HandleRemoteNameResult(TInt aErr, CBTInqResultRef& aRef, const TBTDeviceName8& aBuf);
       
   425 	void TryToInterruptInquiryForNameLookup();
       
   426 	void UpdateNotifiers(const TBTDevAddr& aAddr, const TDesC8& aName);
       
   427 	void ClearCurrentInquiryResults();
       
   428 	TInt CancelHardwareInquiry();
       
   429 	TInt StartHardwareInquiry();
       
   430 
       
   431 	static TInt InquiryWatchdog(TAny* aPtr);
       
   432 	static TInt Flush(TAny* aPtr);
       
   433 	void DoFlush();
       
   434 	void EnableFlusher();
       
   435 
       
   436 	TInt CacheAge(TUint aIAC) const;
       
   437 	void SetCacheAge(TUint aIAC, TInt aAge);
       
   438 	
       
   439 private:
       
   440 	MHCICommandQueue*   iCommandQueue;
       
   441 
       
   442 	// Singleton owner of us
       
   443 	CLinkMgrProtocol& iLinkMgrProtocol;
       
   444 
       
   445 	// What the hardware is currently up to (as far as we know)
       
   446 	THWState		iHWState;
       
   447 	// IAC of the current inquiry
       
   448 	TUint			iCurrentInquiryIAC;
       
   449 	// IAC of the inquiry that is currently requested by a host resolver, either in progress or about to start
       
   450 	TUint			iRequestedInquiryIAC;
       
   451 	// IAC of the inquiry that has been put on hold while a higher priority IAC is in progress
       
   452 	TUint			iQueuedInquiryIAC;
       
   453 	// Number of times we've interrupted the current inquiry
       
   454 	TInt			iInquiryInteruptions;
       
   455 	// Time since the last inquiry, per IAC
       
   456 	RArray<TInquiryCacheAge> iCacheAge;
       
   457 	// Timer to age records and the cache itself
       
   458 	CPeriodic*		iFlusher;
       
   459 	// Results since watchdog last went off
       
   460 	TInt			iResultCount;
       
   461 	// Number of watchdogs seeing 0 devices
       
   462 	TInt			iInquirySilenceCount;
       
   463 	// Number of name requests pending
       
   464 	TInt			iPendingNameRequests;
       
   465 	// True is there are new page requests pending
       
   466 	TInt			iNewPageRequestsPending;
       
   467 	// Current name request pagetimeout
       
   468 	TUint16			iNamePageTimeout;
       
   469 	// Current Inquiry Mode
       
   470 	TUint8			iInquiryMode;
       
   471 	// Pending Inquiry Mode
       
   472 	TUint8			iPendingInquiryMode;
       
   473 
       
   474 	CBTInqResultSet					iCurrentResults;
       
   475 	TDblQue<CBTHostResolver>		iHRs;
       
   476 
       
   477 	TBool			iReportedInquiryState; // what did we last tell the Inquiry state P&S key
       
   478 #ifdef CONNECTION_PREEMPTS_INQUIRY
       
   479 	// Monitors if a ACL connection is currently being established.
       
   480 	CConnectingStatusSubscriber*	iConnectingStatus;
       
   481 #endif
       
   482 	
       
   483 #ifdef _DEBUG
       
   484 	TInt							iNumHRs; // no Count() in que's - handy to have
       
   485 #endif
       
   486 	};
       
   487 
       
   488 #ifdef CONNECTION_PREEMPTS_INQUIRY
       
   489 // *******************************************************************
       
   490 // ACL Connecting status subscriber
       
   491 // *******************************************************************
       
   492 NONSHARABLE_CLASS(CConnectingStatusSubscriber) : public CActive
       
   493 	{
       
   494 public:
       
   495 	static CConnectingStatusSubscriber* NewL(CBTInquiryMgr& aInquiryMgr); 
       
   496 	~CConnectingStatusSubscriber();
       
   497 
       
   498 private:
       
   499 	CConnectingStatusSubscriber(CBTInquiryMgr& aInquiryMgr);
       
   500 	void ConstructL();
       
   501 	void Subscribe();
       
   502 	
       
   503 	void RunL();
       
   504 	void DoCancel();
       
   505 
       
   506 	CBTInquiryMgr& iParent;
       
   507 	RProperty iProperty;
       
   508 	};
       
   509 #endif	// CONNECTION_PREEMPTS_INQUIRY
       
   510 
       
   511 #endif