bluetooth/btstack/linkmgr/hostresolver.cpp
changeset 48 22de2e391156
parent 34 9d84592f5036
child 51 20ac952a623c
equal deleted inserted replaced
35:14e279d2bbb7 48:22de2e391156
   522 	{
   522 	{
   523 	LOG_FUNC
   523 	LOG_FUNC
   524 	__ASSERT_DEBUG(iRequestState == EIdle, Panic(EHostResolverTwoRequests));
   524 	__ASSERT_DEBUG(iRequestState == EIdle, Panic(EHostResolverTwoRequests));
   525 	iNameRecord = &aName;
   525 	iNameRecord = &aName;
   526 	iNameRecord->iName.Zero();
   526 	iNameRecord->iName.Zero();
   527 	TInquirySockAddr& sa = TInquirySockAddr::Cast(aName.iAddr);
   527 	iSockAddr = TInquirySockAddr::Cast(aName.iAddr);
   528 
   528 
   529 	LOG1(_L("Host Resolver\tAction = %d"),sa.Action());
   529 	LOG1(_L("Host Resolver\tAction = %d"),iSockAddr.Action());
   530 
   530 
   531 	if(sa.Action() & KHostResCache)
   531 	if(iSockAddr.Action() & KHostResCache)
   532 		//Complete immediately with info if available!
   532 		//Complete immediately with info if available!
   533 		{
   533 		{
   534 		TInt err = KErrNotFound;
   534 		TInt err = KErrNotFound;
   535 		CBTInqResultRef* ref = iInquiryMgr.FindExistingCacheEntry(sa.BTAddr());
   535 		CBTInqResultRef* ref = iInquiryMgr.FindExistingCacheEntry(iSockAddr.BTAddr());
   536 		if (ref)
   536 		if (ref)
   537 			{// Got a result to send up
   537 			{// Got a result to send up
   538 			CBTInqResultRecord& rec = ref->Result();
   538 			CBTInqResultRecord& rec = ref->Result();
   539 			rec.GetInquirySockAddr(sa); //Put BT address, CoD etc into 'aName'
   539 			rec.GetInquirySockAddr(TInquirySockAddr::Cast(aName.iAddr)); //Put BT address, CoD etc into 'aName'
   540 			// Check whether client wants EIRs instead of names
   540 			// Check whether client wants EIRs instead of names
   541 			if(sa.Action() & KHostResEir)
   541 			if(iSockAddr.Action() & KHostResEir)
   542 				{
   542 				{
   543 				// Client knows about EIR, we'll fill the TNameRecord with EIR
   543 				// Client knows about EIR, we'll fill the TNameRecord with EIR
   544 				err = rec.GetEir(aName, EFalse);
   544 				err = rec.GetEir(aName, EFalse);
   545 				}
   545 				}
   546 			else
   546 			else
   563 		iNotify->QueryComplete(err);
   563 		iNotify->QueryComplete(err);
   564 		return;
   564 		return;
   565 		}
   565 		}
   566 	
   566 	
   567 	// Must request at least one of inquiry or name lookup
   567 	// Must request at least one of inquiry or name lookup
   568 	if (!(sa.Action() & (KHostResInquiry | KHostResName)))
   568 	if (!(iSockAddr.Action() & (KHostResInquiry | KHostResName)))
   569 		{
   569 		{
   570 		iRequestState = EError;
   570 		iRequestState = EError;
   571 		CompleteRequest(KErrArgument);
   571 		CompleteRequest(KErrArgument);
   572 		return;
   572 		return;
   573 		}
   573 		}
   579 		iRequestState = EError;
   579 		iRequestState = EError;
   580 		CompleteRequest(KErrHardwareNotAvailable);
   580 		CompleteRequest(KErrHardwareNotAvailable);
   581 		return;
   581 		return;
   582 		}
   582 		}
   583 
   583 
   584 	iNameLookupMode = (sa.Action()) & KHostResName ? EDoGetNames : EDontGetNames;
   584 	iNameLookupMode = (iSockAddr.Action()) & KHostResName ? EDoGetNames : EDontGetNames;
   585 	TBool ignoreCache = (sa.Action() & KHostResIgnoreCache) ? ETrue : EFalse;
   585 	TBool ignoreCache = (iSockAddr.Action() & KHostResIgnoreCache) ? ETrue : EFalse;
   586 
   586 
   587 	if (sa.Action() & KHostResInquiry)
   587 	if (iSockAddr.Action() & KHostResInquiry)
   588 		{
   588 		{
   589 		// We only support GIAC and LIAC
   589 		// We only support GIAC and LIAC
   590 		if (sa.IAC() != KLIAC && sa.IAC() != KGIAC)
   590 		if (iSockAddr.IAC() != KLIAC && iSockAddr.IAC() != KGIAC)
   591 			{
   591 			{
   592 			iRequestState = EError;
   592 			iRequestState = EError;
   593 			CompleteRequest(KErrNotSupported);
   593 			CompleteRequest(KErrNotSupported);
   594 			return;
   594 			return;
   595 			}
   595 			}
   596 		sa.SetBTAddr(TBTDevAddr());
   596 		iSockAddr.SetBTAddr(TBTDevAddr());
   597 		iRequestState = EInquiry;
   597 		iRequestState = EInquiry;
   598 		if (iInquiryStatus == EInquiryReady)
   598 		if (iInquiryStatus == EInquiryReady)
   599 			{// Need to start the inquiry process
   599 			{// Need to start the inquiry process
   600 			iInquiryStatus = EInquiring;
   600 			iInquiryStatus = EInquiring;
   601 			// We set this before calling StartInquiry, as StartInquiry can call InquiryComplete synchronously. 
   601 			// We set this before calling StartInquiry, as StartInquiry can call InquiryComplete synchronously. 
   602 			iResults.Reset();
   602 			iResults.Reset();
   603 			iInquiryMgr.StartInquiry(*this, sa.IAC(), ignoreCache);
   603 			iInquiryMgr.StartInquiry(*this, iSockAddr.IAC(), ignoreCache);
   604 			}
   604 			}
   605 		}
   605 		}
   606 	else // Not an inquiry - just a name lookup
   606 	else // Not an inquiry - just a name lookup
   607 		{
   607 		{
   608 		// Just name lookup -- add it to the result set, and request a lookup of it
   608 		// Just name lookup -- add it to the result set, and request a lookup of it
   609 		iResults.Reset();
   609 		iResults.Reset();
   610 
   610 
   611 		CBTInqResultRef* ref = iInquiryMgr.AddEntryToCache(sa.BTAddr());
   611 		CBTInqResultRef* ref = iInquiryMgr.AddEntryToCache(iSockAddr.BTAddr());
   612 		if(ref)
   612 		if(ref)
   613 			{// This ref is in cache -- need to make our own ref
   613 			{// This ref is in cache -- need to make our own ref
   614 			ref = iResults.Add(ref->Result());
   614 			ref = iResults.Add(ref->Result());
   615 			}
   615 			}
   616 		if (!ref)
   616 		if (!ref)
   618 			CompleteRequest(KErrNoMemory);
   618 			CompleteRequest(KErrNoMemory);
   619 			return;
   619 			return;
   620 			}
   620 			}
   621 		iResults.NextResult(); // Move iter onto first (only) result
   621 		iResults.NextResult(); // Move iter onto first (only) result
   622 		iRequestState = ENameLookup;
   622 		iRequestState = ENameLookup;
   623 		iInquiryMgr.LookupName(*this, sa.BTAddr(), ignoreCache, ETrue);
   623 		iInquiryMgr.LookupName(*this, iSockAddr.BTAddr(), ignoreCache, ETrue);
   624 		}
   624 		}
   625 	TryToCompleteRequest();
   625 	TryToCompleteRequest();
   626 	}
   626 	}
   627 
   627 
   628 TInt CBTHostResolver::SetOption(TUint /*aLevel*/, TUint /*aName*/, const TDesC8& /*aOption*/)
   628 TInt CBTHostResolver::SetOption(TUint /*aLevel*/, TUint /*aName*/, const TDesC8& /*aOption*/)
   707 	// Check if we've already seen this result
   707 	// Check if we've already seen this result
   708 	CBTInqResultRef* ref = iResults.FindEntry(aResult.LogEntry().iBdaddr);
   708 	CBTInqResultRef* ref = iResults.FindEntry(aResult.LogEntry().iBdaddr);
   709 	if (ref)
   709 	if (ref)
   710 		return;
   710 		return;
   711 
   711 
   712 	TInquirySockAddr& sa = TInquirySockAddr::Cast(iNameRecord->iAddr);
   712 	if(!aResult.HasRespondedToIAC(iSockAddr.IAC()))
   713 	if(!aResult.HasRespondedToIAC(sa.IAC()))
       
   714 		return; // It's never responded to our IAC, so ignore it
   713 		return; // It's never responded to our IAC, so ignore it
   715 
   714 
   716 	ref = iResults.Add(aResult);
   715 	ref = iResults.Add(aResult);
   717 	if (!ref)
   716 	if (!ref)
   718 		{
   717 		{
   721 		}
   720 		}
   722 
   721 
   723 	if(iNameLookupMode == EDoGetNames)
   722 	if(iNameLookupMode == EDoGetNames)
   724 		{
   723 		{
   725 		// Find out whether cache was supposed to be ignored from TNameRecord that was passed into GetByAddress() previously
   724 		// Find out whether cache was supposed to be ignored from TNameRecord that was passed into GetByAddress() previously
   726 		TBool ignoreCache = (sa.Action() & KHostResIgnoreCache) ? ETrue : EFalse;
   725 		TBool ignoreCache = (iSockAddr.Action() & KHostResIgnoreCache) ? ETrue : EFalse;
   727 		// Handle a "special" case: Cache is to be ignored, but we got the _complete_ name during the inquiry process inside an EIR
   726 		// Handle a "special" case: Cache is to be ignored, but we got the _complete_ name during the inquiry process inside an EIR
   728 		// (which doesn't count as cached data, since it's freshly arrived from the radio). In this case we don't really want to 
   727 		// (which doesn't count as cached data, since it's freshly arrived from the radio). In this case we don't really want to 
   729 		// launch a remote name request
   728 		// launch a remote name request
   730 		if(ignoreCache && ref->Result().IsEirPresent() && ref->Result().Codec().IsDataTypePresent(EEirLocalNameComplete))
   729 		if(ignoreCache && ref->Result().IsEirPresent() && ref->Result().Codec().IsDataTypePresent(EEirLocalNameComplete))
   731 			{
   730 			{
   799 	}
   798 	}
   800 
   799 
   801 TUint CBTHostResolver::GetIAC() const
   800 TUint CBTHostResolver::GetIAC() const
   802 	{
   801 	{
   803 	LOG_FUNC
   802 	LOG_FUNC
   804 	if (!iNameRecord)
   803 	TUint ret = 0;
   805 		{
   804 	if (iInquiryStatus == EInquiring)
   806 		return 0;		// avoid dereferencing a null ptr
   805 		{
       
   806 		ret = iSockAddr.IAC(); // Only return IAC if an inquiry is requested
   807 		}
   807 		}
   808 	
   808 	
   809 	TInquirySockAddr& sa = TInquirySockAddr::Cast(iNameRecord->iAddr);
   809 	return ret;
   810 	return sa.IAC();
       
   811 	}
   810 	}
   812 
   811 
   813 TInt CBTHostResolver::SecurityCheck(MProvdSecurityChecker *aSecurityChecker)
   812 TInt CBTHostResolver::SecurityCheck(MProvdSecurityChecker *aSecurityChecker)
   814 	{
   813 	{
   815 	LOG_FUNC
   814 	LOG_FUNC
   831 	Must only break out (i.e. return) if the request is completed, or
   830 	Must only break out (i.e. return) if the request is completed, or
   832 	non-blocking mode requested
   831 	non-blocking mode requested
   833 **/
   832 **/
   834 	{
   833 	{
   835 	LOG_FUNC
   834 	LOG_FUNC
   836 	TInquirySockAddr& sa = TInquirySockAddr::Cast(iNameRecord->iAddr);
   835 	if ((iSockAddr.Action() & KHostResInquiry) && iRequestState == EInquiry)
   837 	if ((sa.Action() & KHostResInquiry) && iRequestState == EInquiry)
       
   838 		{
   836 		{
   839 		CBTInqResultRef* refNextRes = iResults.NextResult();
   837 		CBTInqResultRef* refNextRes = iResults.NextResult();
   840 		if (refNextRes)
   838 		if (refNextRes)
   841 			{// Got a result to send up
   839 			{// Got a result to send up
   842 			if (iNameLookupMode == EDoGetNames)
   840 			if (iNameLookupMode == EDoGetNames)
   843 				{// Need to get the name of this baby...
   841 				{// Need to get the name of this baby...
   844 				iRequestState = ENameLookup;
   842 				iRequestState = ENameLookup;
   845 				}
   843 				}
   846 			else
   844 			else
   847 				{//Complete!
   845 				{//Complete!
   848 				refNextRes->Result().GetInquirySockAddr(sa);
   846 				refNextRes->Result().GetInquirySockAddr(TInquirySockAddr::Cast(iNameRecord->iAddr));
   849 				// If EIR was requested and we got one, stick it in the name field
   847 				// If EIR was requested and we got one, stick it in the name field
   850 				TInt err = KErrNone;
   848 				TInt err = KErrNone;
   851 				if(sa.Action() & KHostResEir)
   849 				if(iSockAddr.Action() & KHostResEir)
   852 					{
   850 					{
   853 					err = refNextRes->Result().GetEir(*iNameRecord, (sa.Action() & KHostResIgnoreCache) && !(sa.Action() & KHostResName));
   851 					err = refNextRes->Result().GetEir(*iNameRecord, (iSockAddr.Action() & KHostResIgnoreCache) && !(iSockAddr.Action() & KHostResName));
   854 					}
   852 					}
   855 				else
   853 				else
   856 					{
   854 					{
   857 					err = refNextRes->Result().GetName(*iNameRecord);
   855 					err = refNextRes->Result().GetName(*iNameRecord);
   858 					}
   856 					}
   877 				}
   875 				}
   878 			return;
   876 			return;
   879 			}
   877 			}
   880 		}
   878 		}
   881 
   879 
   882 	if ((sa.Action() & KHostResName) && iRequestState == ENameLookup)
   880 	if ((iSockAddr.Action() & KHostResName) && iRequestState == ENameLookup)
   883 		{
   881 		{
   884 		CBTInqResultRef* refNextRes = iResults.CurrentResult();
   882 		CBTInqResultRef* refNextRes = iResults.CurrentResult();
   885 		if(!refNextRes)
   883 		if(!refNextRes)
   886 			{// Can't get the name... no result to lookup
   884 			{// Can't get the name... no result to lookup
   887 			CompleteRequest(KErrHostResNoMoreResults);
   885 			CompleteRequest(KErrHostResNoMoreResults);
   892 		do
   890 		do
   893 			{
   891 			{
   894 			CBTInqResultRecord& rec = refNextRes->Result();
   892 			CBTInqResultRecord& rec = refNextRes->Result();
   895 			if(rec.HaveNameLookupResult() && !rec.IsNameRequestPending() && rec.IsNameComplete())
   893 			if(rec.HaveNameLookupResult() && !rec.IsNameRequestPending() && rec.IsNameComplete())
   896 				{// Got a name! Complete the request
   894 				{// Got a name! Complete the request
   897 				rec.GetInquirySockAddr(sa);
   895 				rec.GetInquirySockAddr(TInquirySockAddr::Cast(iNameRecord->iAddr));
   898 				TInt err = rec.NameLookupResultCode();
   896 				TInt err = rec.NameLookupResultCode();
   899 				if (err == KErrNone)
   897 				if (err == KErrNone)
   900 					{// Copy & convert the UTF-8 name over into the result record.
   898 					{// Copy & convert the UTF-8 name over into the result record.
   901 					if(sa.Action() & KHostResEir)
   899 					if(iSockAddr.Action() & KHostResEir)
   902 						{
   900 						{
   903 						err = rec.GetEir(*iNameRecord, EFalse);
   901 						err = rec.GetEir(*iNameRecord, EFalse);
   904 						}
   902 						}
   905 					else
   903 					else
   906 						{
   904 						{
   910 				if (err != KErrNone)
   908 				if (err != KErrNone)
   911 					{
   909 					{
   912 					iNameRecord->iName.Zero();
   910 					iNameRecord->iName.Zero();
   913 					}
   911 					}
   914 				// Name lookup complete (poss. with errors)
   912 				// Name lookup complete (poss. with errors)
   915 				if(sa.Action() & KHostResInquiry)
   913 				if(iSockAddr.Action() & KHostResInquiry)
   916 					{// Ignore name failures if we're also doing inquiry
   914 					{// Ignore name failures if we're also doing inquiry
   917 					CompleteRequest(KErrNone);
   915 					CompleteRequest(KErrNone);
   918 					}
   916 					}
   919 				else
   917 				else
   920 					{// Report any error encountered (or none)
   918 					{// Report any error encountered (or none)
   929 		}
   927 		}
   930 	else if(iRequestState==EError)
   928 	else if(iRequestState==EError)
   931 		{
   929 		{
   932 		CompleteRequest(KErrHardwareNotAvailable);
   930 		CompleteRequest(KErrHardwareNotAvailable);
   933 		}
   931 		}
   934 	if(sa.Action() & KHostResDontBlock)
   932 	if(iSockAddr.Action() & KHostResDontBlock)
   935 		{// Complete any outstanding non-blocking operation
   933 		{// Complete any outstanding non-blocking operation
   936 		CompleteRequest(KErrWouldBlock);
   934 		CompleteRequest(KErrWouldBlock);
   937 		}
   935 		}
   938 
   936 
   939 	}
   937 	}
  1045 	}
  1043 	}
  1046 
  1044 
  1047 void CBTInquiryMgr::DeletingHostResolver()
  1045 void CBTInquiryMgr::DeletingHostResolver()
  1048 	{
  1046 	{
  1049 	LOG_FUNC
  1047 	LOG_FUNC
  1050 	// A host resolver is being deleted - we need to check if any other host resolvers want inquiry results from the current IAC.
  1048 	// A host resolver is being deleted - we need to check if we need to change IAC.
  1051 	if(!iRequestedInquiryIAC)
  1049 	// If no host resolver is requesting an inquiry, just let the inquiry run to fill up the cache 
  1052 		{
  1050 	TUint requestedIAC = RequestedInquiryIAC();
  1053 		 //No 'current' IAC exists
  1051 	if (iHWState == EInquiry && requestedIAC != 0 && iCurrentInquiryIAC != requestedIAC)
  1054 		 return;		 
  1052 		{
  1055 		}
  1053 		TInt err = CancelHardwareInquiry();
  1056 	TDblQueIter<CBTHostResolver> iter(iHRs);
  1054 		if(err==KErrNone)
  1057 	TBool iacFound=EFalse;
  1055 			{
  1058 	while (iter)
  1056 			SetHWState(ECancellingForNewIAC);
  1059 		{
  1057 			iFlusher->Cancel();     // Stop watchdog, start flusher.
  1060 		if ((iter++)->GetIAC() == iRequestedInquiryIAC)
  1058 			}
  1061 			{
  1059 		}
  1062 			iacFound = ETrue;
  1060 	}
  1063 			}
  1061 
  1064 		}
  1062 TUint CBTInquiryMgr::RequestedInquiryIAC()
  1065 	if (!iacFound)
  1063     {
  1066 		{
  1064     TUint ret = 0;
  1067 		iRequestedInquiryIAC = 0;
  1065     TDblQueIter<CBTHostResolver> iter(iHRs);
  1068 		}
  1066     CBTHostResolver* hostRes = NULL;
  1069 	}
  1067     while ((hostRes = iter++) != NULL)
       
  1068         {
       
  1069     	// Only overwrite the requested IAC if:
       
  1070     	// - We haven't found a host resolver requesting an IAC yet, or
       
  1071     	// - This host resolver requests LIAC, which we prioritise over GIAC
       
  1072         if (ret == 0 || hostRes->GetIAC() == KLIAC)
       
  1073             {
       
  1074             ret = hostRes->GetIAC();
       
  1075             }
       
  1076         }
       
  1077     return ret;
       
  1078     }
  1070 
  1079 
  1071 void CBTInquiryMgr::InquiryResult(TInt aErr,const TInquiryLogEntry& aEntry)
  1080 void CBTInquiryMgr::InquiryResult(TInt aErr,const TInquiryLogEntry& aEntry)
  1072 /**
  1081 /**
  1073 	Single Inquiry result received.
  1082 	Single Inquiry result received.
  1074 	Called via HCI for each incoming inquiry result. Need to demultiplex these
  1083 	Called via HCI for each incoming inquiry result. Need to demultiplex these
  1172 					have been generated. We don't use this info atm, though.
  1181 					have been generated. We don't use this info atm, though.
  1173 **/
  1182 **/
  1174 	{
  1183 	{
  1175 	LOG_FUNC
  1184 	LOG_FUNC
  1176 	SetCacheAge(iCurrentInquiryIAC, 0);
  1185 	SetCacheAge(iCurrentInquiryIAC, 0);
  1177 	TUint iacToComplete = iRequestedInquiryIAC;
  1186 	TUint iacToComplete = iCurrentInquiryIAC;
  1178 	iRequestedInquiryIAC = 0;
  1187 	iCurrentInquiryIAC = 0;
  1179 	iFlusher->Cancel(); // Stop watchdog, start flusher
  1188 	iFlusher->Cancel(); // Stop watchdog, start flusher
  1180 	SetHWState(EIdle);
  1189 	SetHWState(EIdle);
  1181 	// don't publish status here, might be doing a name lookup
  1190 	// don't publish status here, might be doing a name lookup
  1182 	EnableFlusher();
  1191 	EnableFlusher();
  1183 
  1192 
  1206 			}
  1215 			}
  1207 		hr++;
  1216 		hr++;
  1208 		}
  1217 		}
  1209 	// Only queue the inquiry if we have completed all the name requests from this one.
  1218 	// Only queue the inquiry if we have completed all the name requests from this one.
  1210 	// Otherwise, it will be issued after all the remote name requests have completed.
  1219 	// Otherwise, it will be issued after all the remote name requests have completed.
  1211 	if (iQueuedInquiryIAC != 0 && iPendingNameRequests == 0)
  1220 	if (RequestedInquiryIAC() != 0 && iPendingNameRequests == 0)
  1212 		{
  1221 		{
  1213 		iRequestedInquiryIAC = iQueuedInquiryIAC;
       
  1214 		iQueuedInquiryIAC = 0;
       
  1215 		DoInquiry();
  1222 		DoInquiry();
  1216 		}
  1223 		}
  1217 	}
  1224 	}
  1218 
  1225 
  1219 /**
  1226 /**
  1382 			}
  1389 			}
  1383 		}
  1390 		}
  1384 
  1391 
  1385 	// In case we're now free, do inquiry
  1392 	// In case we're now free, do inquiry
  1386 	LOG(_L("CBTInquiryMgr::HandleRemoteNameResult asking for another inquiry"));
  1393 	LOG(_L("CBTInquiryMgr::HandleRemoteNameResult asking for another inquiry"));
  1387 	if (iPendingNameRequests == 0 && iRequestedInquiryIAC == 0) // If we've completed the current inquiry, see if we've got another one queued.
       
  1388 		{
       
  1389 		iRequestedInquiryIAC = iQueuedInquiryIAC;
       
  1390 		iQueuedInquiryIAC = 0;
       
  1391 		}
       
  1392 	DoInquiry();
  1394 	DoInquiry();
  1393 	}
  1395 	}
  1394 
  1396 
  1395 const TDesC8* CBTInquiryMgr::DeviceNameFromCache(const TBTDevAddr& aAddr)
  1397 const TDesC8* CBTInquiryMgr::DeviceNameFromCache(const TBTDevAddr& aAddr)
  1396 /**
  1398 /**
  1523 		LOG(_L("CBTInquiryMgr::StartInquiry giving result from cache"));
  1525 		LOG(_L("CBTInquiryMgr::StartInquiry giving result from cache"));
  1524 		aResolver.InquiryComplete(KErrNone);
  1526 		aResolver.InquiryComplete(KErrNone);
  1525 		return;
  1527 		return;
  1526 		}
  1528 		}
  1527 	
  1529 	
  1528 	if (iRequestedInquiryIAC || iQueuedInquiryIAC)
  1530 	if (iCurrentInquiryIAC)
  1529 		{
  1531 		{
  1530 		LOG(_L("CBTInquiryMgr::StartInquiry iRequestedInquiryIAC"));
  1532 		LOG(_L("CBTInquiryMgr::StartInquiry"));
  1531 		if(iRequestedInquiryIAC == aIAC)
  1533         if (aIgnoreCache && (aIAC == iCurrentInquiryIAC || aIAC == KGIAC))
  1532 			{
  1534             {
  1533 			// an Inquiry is ongoing, return any results already found during the
  1535             // an Inquiry is ongoing, return any results already found during the
  1534 			// current Inquiry if not already done so as part of the complete cache
  1536             // current Inquiry if not already done so as part of the complete cache
  1535 			if (aIgnoreCache)
  1537             iCurrentResults.ReturnToFirstResult();
  1536 				{
  1538             while (CBTInqResultRef* ref = iCurrentResults.NextResult())
  1537 				iCurrentResults.ReturnToFirstResult();
  1539                 {
  1538 				while (CBTInqResultRef* ref = iCurrentResults.NextResult())
  1540                 if (ref->Result().iFoundDuringCurrentInquiry)
  1539 					{
  1541                     {
  1540 					if (ref->Result().iFoundDuringCurrentInquiry)
  1542                     aResolver.InquiryResult(ref->Result());
  1541 						{
  1543                     }
  1542 						aResolver.InquiryResult(ref->Result());
  1544                 }   
  1543 						}
  1545             }
  1544 					}	
  1546 		if(iCurrentInquiryIAC == aIAC)
  1545 				}
  1547 			{
  1546 			// the current Inquiry will just continue
  1548 			// the current Inquiry will just continue
  1547 			return;			
  1549 			return;			
  1548 			}
  1550 			}
  1549 		if (aIAC == KGIAC)
  1551 		if(iHWState == EInquiry && RequestedInquiryIAC() != iCurrentInquiryIAC)
  1550 			{
  1552 			{
  1551 			// If the current IAC is GIAC, and the requested inquiry IAC isn't, it must be LIAC
  1553 			// The requested IAC (which prioritises LIAC) is different to the current IAC, so cancel to change the IAC
  1552 			__ASSERT_DEBUG(iRequestedInquiryIAC == KLIAC, Panic(EBTUnexpectedIAC)); 
       
  1553 			// Queue a general inquiry for when the current limited inquiry has finished
       
  1554 			iQueuedInquiryIAC = aIAC;
       
  1555 			return;
       
  1556 			}
       
  1557 		else if(iHWState == EInquiry)
       
  1558 			{
       
  1559 			// The host resolver should only allow through GIAC and LIAC, and we handle GIAC above
       
  1560 			__ASSERT_DEBUG(aIAC == KLIAC, Panic(EBTUnexpectedIAC)); 
       
  1561 			// We favour a Limited inqiury, so interrupt the current general inquiry
       
  1562 			TInt err = CancelHardwareInquiry();
  1554 			TInt err = CancelHardwareInquiry();
  1563 			if(err!=KErrNone)
  1555 			if(err!=KErrNone)
  1564 				{
  1556 				{
  1565 				LOG(_L("CBTInquiryMgr::StartInquiry cancel didn't work"));
  1557 				LOG(_L("CBTInquiryMgr::StartInquiry cancel didn't work"));
  1566 				aResolver.InquiryComplete(err); // cancel went wrong
  1558 				aResolver.InquiryComplete(err); // cancel went wrong
  1567 				return;
  1559 				return;
  1568 				}
  1560 				}
  1569 			// Queue a general inquiry for when the limited inquiry is complete
       
  1570 			iRequestedInquiryIAC = KLIAC;
       
  1571 			iQueuedInquiryIAC = KGIAC;
       
  1572 			SetHWState(ECancellingForNewIAC);
  1561 			SetHWState(ECancellingForNewIAC);
  1573 			iFlusher->Cancel(); 	// Stop watchdog, start flusher.
  1562 			iFlusher->Cancel(); 	// Stop watchdog, start flusher.
  1574 			return;
  1563 			return;
  1575 			}
  1564 			}
  1576 		else
  1565 		}
  1577 			{
  1566 
  1578 			// The host resolver should only allow through GIAC and LIAC, and we handle GIAC above
       
  1579 			__ASSERT_DEBUG(aIAC == KLIAC, Panic(EBTUnexpectedIAC)); 
       
  1580 			iRequestedInquiryIAC = KLIAC;
       
  1581 			iQueuedInquiryIAC = KGIAC;
       
  1582 			}
       
  1583 		}
       
  1584 
       
  1585 	iRequestedInquiryIAC = aIAC;
       
  1586 	iInquiryInteruptions = 0;
  1567 	iInquiryInteruptions = 0;
  1587 
  1568 
  1588 	DoInquiry();
  1569 	DoInquiry();
  1589 	}
  1570 	}
  1590 
  1571 
  1800 	Only starts it if there isn't already one going.
  1781 	Only starts it if there isn't already one going.
  1801 **/
  1782 **/
  1802 	{
  1783 	{
  1803 	LOG_FUNC
  1784 	LOG_FUNC
  1804 
  1785 
  1805 	if(iRequestedInquiryIAC == 0 || iHWState != EIdle || iHRs.IsEmpty())
  1786 	if(RequestedInquiryIAC() == 0 || iHWState != EIdle || iHRs.IsEmpty())
  1806 		{
  1787 		{
  1807 #ifdef _DEBUG
  1788 #ifdef _DEBUG
  1808 		LOG3(_L("Not starting inquiry. iRequestedInquiryIAC == %d, iHWState == %d, iHostResolverCount == %d"), iRequestedInquiryIAC, iHWState, iNumHRs);
  1789 		LOG3(_L("Not starting inquiry. RequestedInquiryIAC == %d, iHWState == %d, iHostResolverCount == %d"), RequestedInquiryIAC(), iHWState, iNumHRs);
  1809 		if (iHRs.IsEmpty())
  1790 		if (iHRs.IsEmpty())
  1810 			{
  1791 			{
  1811 			LOG(_L("No HRs interested in results - Stopping discovery"));
  1792 			LOG(_L("No HRs interested in results - Stopping discovery"));
  1812 			}
  1793 			}
  1813 #endif
  1794 #endif
  1814 		if (iHWState == EIdle)
  1795 		if (iHWState == EIdle)
  1815 			{
  1796 			{
  1816 			LOG(_L("CBTInquiryMgr::DoInquiry PublishStatus Idle"));	
  1797 			LOG(_L("CBTInquiryMgr::DoInquiry PublishStatus Idle"));	
  1817 			PublishStatus();// make sure the status says we're idle
  1798 			PublishStatus();// make sure the status says we're idle
       
  1799 			}
       
  1800 		if (RequestedInquiryIAC() == 0)
       
  1801 			{
       
  1802 			iCurrentInquiryIAC = 0;
  1818 			}
  1803 			}
  1819 		return;
  1804 		return;
  1820 		}
  1805 		}
  1821 
  1806 
  1822 	// If pending on name lookup, we'll do it when that finishes
  1807 	// If pending on name lookup, we'll do it when that finishes
  1843 		}
  1828 		}
  1844 	else
  1829 	else
  1845 		{
  1830 		{
  1846 		// Couldn't start inquiry.
  1831 		// Couldn't start inquiry.
  1847 		// Make sure the request is completed.
  1832 		// Make sure the request is completed.
  1848 		iRequestedInquiryIAC = 0;
  1833 		iCurrentInquiryIAC = 0;
  1849 		InquiryComplete(err, 0);
  1834 		InquiryComplete(err, 0);
  1850 		LOG(_L("CBTInquiryMgr::DoInquiry PublishState Idle couldn't start inquiry"));
  1835 		LOG(_L("CBTInquiryMgr::DoInquiry PublishState Idle couldn't start inquiry"));
  1851 		PublishStatus();
  1836 		PublishStatus();
  1852 		return;
  1837 		return;
  1853 		}
  1838 		}
  1875 	}
  1860 	}
  1876 
  1861 
  1877 TInt CBTInquiryMgr::StartHardwareInquiry()
  1862 TInt CBTInquiryMgr::StartHardwareInquiry()
  1878 	{
  1863 	{
  1879 	LOG_FUNC
  1864 	LOG_FUNC
  1880 	iCurrentInquiryIAC = iRequestedInquiryIAC;
  1865 	iCurrentInquiryIAC = RequestedInquiryIAC();
  1881 	// attempt to free up baseband space for best performance discovery
  1866 	// attempt to free up baseband space for best performance discovery
  1882 	iLinkMgrProtocol.PhysicalLinksMgr().RequireSlotSpace(); // will *eventually* put connections in hold - we dont wait though
  1867 	iLinkMgrProtocol.PhysicalLinksMgr().RequireSlotSpace(); // will *eventually* put connections in hold - we dont wait though
  1883 	TRAPD(err, StartInquiryL(iCurrentInquiryIAC, KInquiryLength, KInquiryMaxResults));
  1868 	TRAPD(err, StartInquiryL(iCurrentInquiryIAC, KInquiryLength, KInquiryMaxResults));
  1884 
  1869 
  1885 	return err;
  1870 	return err;
  1921 	while(CBTInqResultRef *ref = iCurrentResults.NextResult())
  1906 	while(CBTInqResultRef *ref = iCurrentResults.NextResult())
  1922 		{
  1907 		{
  1923 		CBTInqResultRecord& rec = ref->Result();
  1908 		CBTInqResultRecord& rec = ref->Result();
  1924 		if(rec.IsNameRequestPending())
  1909 		if(rec.IsNameRequestPending())
  1925 			{
  1910 			{
  1926 			if(!iRequestedInquiryIAC ||
  1911 			if(RequestedInquiryIAC() == 0 || rec.NameLookupAttempts() < KMaxNameLookupAttemptsDuringInquiry)
  1927 			   rec.NameLookupAttempts() < KMaxNameLookupAttemptsDuringInquiry)
       
  1928 				{
  1912 				{
  1929 				// We want the first record for the current IAC or a record for an explicit name request.
  1913 				// We want the first record for the current IAC or a record for an explicit name request.
  1930 				// Failing that, we'll just have the first record
  1914 				// Failing that, we'll just have the first record
  1931 				if (rec.HasRespondedToIAC(iCurrentInquiryIAC) || rec.IsExplicitNameRequest())
  1915 				if (rec.HasRespondedToIAC(iCurrentInquiryIAC) || rec.IsExplicitNameRequest())
  1932 					{
  1916 					{