--- a/bluetooth/btstack/linkmgr/hostresolver.cpp Wed Jul 21 15:42:05 2010 +0300
+++ b/bluetooth/btstack/linkmgr/hostresolver.cpp Thu Sep 23 17:06:47 2010 +0300
@@ -524,21 +524,21 @@
__ASSERT_DEBUG(iRequestState == EIdle, Panic(EHostResolverTwoRequests));
iNameRecord = &aName;
iNameRecord->iName.Zero();
- TInquirySockAddr& sa = TInquirySockAddr::Cast(aName.iAddr);
+ iSockAddr = TInquirySockAddr::Cast(aName.iAddr);
- LOG1(_L("Host Resolver\tAction = %d"),sa.Action());
+ LOG1(_L("Host Resolver\tAction = %d"),iSockAddr.Action());
- if(sa.Action() & KHostResCache)
+ if(iSockAddr.Action() & KHostResCache)
//Complete immediately with info if available!
{
TInt err = KErrNotFound;
- CBTInqResultRef* ref = iInquiryMgr.FindExistingCacheEntry(sa.BTAddr());
+ CBTInqResultRef* ref = iInquiryMgr.FindExistingCacheEntry(iSockAddr.BTAddr());
if (ref)
{// Got a result to send up
CBTInqResultRecord& rec = ref->Result();
- rec.GetInquirySockAddr(sa); //Put BT address, CoD etc into 'aName'
+ rec.GetInquirySockAddr(TInquirySockAddr::Cast(aName.iAddr)); //Put BT address, CoD etc into 'aName'
// Check whether client wants EIRs instead of names
- if(sa.Action() & KHostResEir)
+ if(iSockAddr.Action() & KHostResEir)
{
// Client knows about EIR, we'll fill the TNameRecord with EIR
err = rec.GetEir(aName, EFalse);
@@ -565,7 +565,7 @@
}
// Must request at least one of inquiry or name lookup
- if (!(sa.Action() & (KHostResInquiry | KHostResName)))
+ if (!(iSockAddr.Action() & (KHostResInquiry | KHostResName)))
{
iRequestState = EError;
CompleteRequest(KErrArgument);
@@ -581,26 +581,26 @@
return;
}
- iNameLookupMode = (sa.Action()) & KHostResName ? EDoGetNames : EDontGetNames;
- TBool ignoreCache = (sa.Action() & KHostResIgnoreCache) ? ETrue : EFalse;
+ iNameLookupMode = (iSockAddr.Action()) & KHostResName ? EDoGetNames : EDontGetNames;
+ TBool ignoreCache = (iSockAddr.Action() & KHostResIgnoreCache) ? ETrue : EFalse;
- if (sa.Action() & KHostResInquiry)
+ if (iSockAddr.Action() & KHostResInquiry)
{
// We only support GIAC and LIAC
- if (sa.IAC() != KLIAC && sa.IAC() != KGIAC)
+ if (iSockAddr.IAC() != KLIAC && iSockAddr.IAC() != KGIAC)
{
iRequestState = EError;
CompleteRequest(KErrNotSupported);
return;
}
- sa.SetBTAddr(TBTDevAddr());
+ iSockAddr.SetBTAddr(TBTDevAddr());
iRequestState = EInquiry;
if (iInquiryStatus == EInquiryReady)
{// Need to start the inquiry process
iInquiryStatus = EInquiring;
// We set this before calling StartInquiry, as StartInquiry can call InquiryComplete synchronously.
iResults.Reset();
- iInquiryMgr.StartInquiry(*this, sa.IAC(), ignoreCache);
+ iInquiryMgr.StartInquiry(*this, iSockAddr.IAC(), ignoreCache);
}
}
else // Not an inquiry - just a name lookup
@@ -608,7 +608,7 @@
// Just name lookup -- add it to the result set, and request a lookup of it
iResults.Reset();
- CBTInqResultRef* ref = iInquiryMgr.AddEntryToCache(sa.BTAddr());
+ CBTInqResultRef* ref = iInquiryMgr.AddEntryToCache(iSockAddr.BTAddr());
if(ref)
{// This ref is in cache -- need to make our own ref
ref = iResults.Add(ref->Result());
@@ -620,7 +620,7 @@
}
iResults.NextResult(); // Move iter onto first (only) result
iRequestState = ENameLookup;
- iInquiryMgr.LookupName(*this, sa.BTAddr(), ignoreCache, ETrue);
+ iInquiryMgr.LookupName(*this, iSockAddr.BTAddr(), ignoreCache, ETrue);
}
TryToCompleteRequest();
}
@@ -709,8 +709,7 @@
if (ref)
return;
- TInquirySockAddr& sa = TInquirySockAddr::Cast(iNameRecord->iAddr);
- if(!aResult.HasRespondedToIAC(sa.IAC()))
+ if(!aResult.HasRespondedToIAC(iSockAddr.IAC()))
return; // It's never responded to our IAC, so ignore it
ref = iResults.Add(aResult);
@@ -723,7 +722,7 @@
if(iNameLookupMode == EDoGetNames)
{
// Find out whether cache was supposed to be ignored from TNameRecord that was passed into GetByAddress() previously
- TBool ignoreCache = (sa.Action() & KHostResIgnoreCache) ? ETrue : EFalse;
+ TBool ignoreCache = (iSockAddr.Action() & KHostResIgnoreCache) ? ETrue : EFalse;
// Handle a "special" case: Cache is to be ignored, but we got the _complete_ name during the inquiry process inside an EIR
// (which doesn't count as cached data, since it's freshly arrived from the radio). In this case we don't really want to
// launch a remote name request
@@ -801,13 +800,13 @@
TUint CBTHostResolver::GetIAC() const
{
LOG_FUNC
- if (!iNameRecord)
+ TUint ret = 0;
+ if (iInquiryStatus == EInquiring)
{
- return 0; // avoid dereferencing a null ptr
+ ret = iSockAddr.IAC(); // Only return IAC if an inquiry is requested
}
- TInquirySockAddr& sa = TInquirySockAddr::Cast(iNameRecord->iAddr);
- return sa.IAC();
+ return ret;
}
TInt CBTHostResolver::SecurityCheck(MProvdSecurityChecker *aSecurityChecker)
@@ -833,8 +832,7 @@
**/
{
LOG_FUNC
- TInquirySockAddr& sa = TInquirySockAddr::Cast(iNameRecord->iAddr);
- if ((sa.Action() & KHostResInquiry) && iRequestState == EInquiry)
+ if ((iSockAddr.Action() & KHostResInquiry) && iRequestState == EInquiry)
{
CBTInqResultRef* refNextRes = iResults.NextResult();
if (refNextRes)
@@ -845,12 +843,12 @@
}
else
{//Complete!
- refNextRes->Result().GetInquirySockAddr(sa);
+ refNextRes->Result().GetInquirySockAddr(TInquirySockAddr::Cast(iNameRecord->iAddr));
// If EIR was requested and we got one, stick it in the name field
TInt err = KErrNone;
- if(sa.Action() & KHostResEir)
+ if(iSockAddr.Action() & KHostResEir)
{
- err = refNextRes->Result().GetEir(*iNameRecord, (sa.Action() & KHostResIgnoreCache) && !(sa.Action() & KHostResName));
+ err = refNextRes->Result().GetEir(*iNameRecord, (iSockAddr.Action() & KHostResIgnoreCache) && !(iSockAddr.Action() & KHostResName));
}
else
{
@@ -879,7 +877,7 @@
}
}
- if ((sa.Action() & KHostResName) && iRequestState == ENameLookup)
+ if ((iSockAddr.Action() & KHostResName) && iRequestState == ENameLookup)
{
CBTInqResultRef* refNextRes = iResults.CurrentResult();
if(!refNextRes)
@@ -894,11 +892,11 @@
CBTInqResultRecord& rec = refNextRes->Result();
if(rec.HaveNameLookupResult() && !rec.IsNameRequestPending() && rec.IsNameComplete())
{// Got a name! Complete the request
- rec.GetInquirySockAddr(sa);
+ rec.GetInquirySockAddr(TInquirySockAddr::Cast(iNameRecord->iAddr));
TInt err = rec.NameLookupResultCode();
if (err == KErrNone)
{// Copy & convert the UTF-8 name over into the result record.
- if(sa.Action() & KHostResEir)
+ if(iSockAddr.Action() & KHostResEir)
{
err = rec.GetEir(*iNameRecord, EFalse);
}
@@ -912,7 +910,7 @@
iNameRecord->iName.Zero();
}
// Name lookup complete (poss. with errors)
- if(sa.Action() & KHostResInquiry)
+ if(iSockAddr.Action() & KHostResInquiry)
{// Ignore name failures if we're also doing inquiry
CompleteRequest(KErrNone);
}
@@ -931,7 +929,7 @@
{
CompleteRequest(KErrHardwareNotAvailable);
}
- if(sa.Action() & KHostResDontBlock)
+ if(iSockAddr.Action() & KHostResDontBlock)
{// Complete any outstanding non-blocking operation
CompleteRequest(KErrWouldBlock);
}
@@ -1047,27 +1045,38 @@
void CBTInquiryMgr::DeletingHostResolver()
{
LOG_FUNC
- // A host resolver is being deleted - we need to check if any other host resolvers want inquiry results from the current IAC.
- if(!iRequestedInquiryIAC)
+ // A host resolver is being deleted - we need to check if we need to change IAC.
+ // If no host resolver is requesting an inquiry, just let the inquiry run to fill up the cache
+ TUint requestedIAC = RequestedInquiryIAC();
+ if (iHWState == EInquiry && requestedIAC != 0 && iCurrentInquiryIAC != requestedIAC)
{
- //No 'current' IAC exists
- return;
- }
- TDblQueIter<CBTHostResolver> iter(iHRs);
- TBool iacFound=EFalse;
- while (iter)
- {
- if ((iter++)->GetIAC() == iRequestedInquiryIAC)
+ TInt err = CancelHardwareInquiry();
+ if(err==KErrNone)
{
- iacFound = ETrue;
+ SetHWState(ECancellingForNewIAC);
+ iFlusher->Cancel(); // Stop watchdog, start flusher.
}
}
- if (!iacFound)
- {
- iRequestedInquiryIAC = 0;
- }
}
+TUint CBTInquiryMgr::RequestedInquiryIAC()
+ {
+ TUint ret = 0;
+ TDblQueIter<CBTHostResolver> iter(iHRs);
+ CBTHostResolver* hostRes = NULL;
+ while ((hostRes = iter++) != NULL)
+ {
+ // Only overwrite the requested IAC if:
+ // - We haven't found a host resolver requesting an IAC yet, or
+ // - This host resolver requests LIAC, which we prioritise over GIAC
+ if (ret == 0 || hostRes->GetIAC() == KLIAC)
+ {
+ ret = hostRes->GetIAC();
+ }
+ }
+ return ret;
+ }
+
void CBTInquiryMgr::InquiryResult(TInt aErr,const TInquiryLogEntry& aEntry)
/**
Single Inquiry result received.
@@ -1174,8 +1183,8 @@
{
LOG_FUNC
SetCacheAge(iCurrentInquiryIAC, 0);
- TUint iacToComplete = iRequestedInquiryIAC;
- iRequestedInquiryIAC = 0;
+ TUint iacToComplete = iCurrentInquiryIAC;
+ iCurrentInquiryIAC = 0;
iFlusher->Cancel(); // Stop watchdog, start flusher
SetHWState(EIdle);
// don't publish status here, might be doing a name lookup
@@ -1208,10 +1217,8 @@
}
// Only queue the inquiry if we have completed all the name requests from this one.
// Otherwise, it will be issued after all the remote name requests have completed.
- if (iQueuedInquiryIAC != 0 && iPendingNameRequests == 0)
+ if (RequestedInquiryIAC() != 0 && iPendingNameRequests == 0)
{
- iRequestedInquiryIAC = iQueuedInquiryIAC;
- iQueuedInquiryIAC = 0;
DoInquiry();
}
}
@@ -1384,11 +1391,6 @@
// In case we're now free, do inquiry
LOG(_L("CBTInquiryMgr::HandleRemoteNameResult asking for another inquiry"));
- if (iPendingNameRequests == 0 && iRequestedInquiryIAC == 0) // If we've completed the current inquiry, see if we've got another one queued.
- {
- iRequestedInquiryIAC = iQueuedInquiryIAC;
- iQueuedInquiryIAC = 0;
- }
DoInquiry();
}
@@ -1525,40 +1527,30 @@
return;
}
- if (iRequestedInquiryIAC || iQueuedInquiryIAC)
+ if (iCurrentInquiryIAC)
{
- LOG(_L("CBTInquiryMgr::StartInquiry iRequestedInquiryIAC"));
- if(iRequestedInquiryIAC == aIAC)
+ LOG(_L("CBTInquiryMgr::StartInquiry"));
+ if (aIgnoreCache && (aIAC == iCurrentInquiryIAC || aIAC == KGIAC))
+ {
+ // an Inquiry is ongoing, return any results already found during the
+ // current Inquiry if not already done so as part of the complete cache
+ iCurrentResults.ReturnToFirstResult();
+ while (CBTInqResultRef* ref = iCurrentResults.NextResult())
+ {
+ if (ref->Result().iFoundDuringCurrentInquiry)
+ {
+ aResolver.InquiryResult(ref->Result());
+ }
+ }
+ }
+ if(iCurrentInquiryIAC == aIAC)
{
- // an Inquiry is ongoing, return any results already found during the
- // current Inquiry if not already done so as part of the complete cache
- if (aIgnoreCache)
- {
- iCurrentResults.ReturnToFirstResult();
- while (CBTInqResultRef* ref = iCurrentResults.NextResult())
- {
- if (ref->Result().iFoundDuringCurrentInquiry)
- {
- aResolver.InquiryResult(ref->Result());
- }
- }
- }
// the current Inquiry will just continue
return;
}
- if (aIAC == KGIAC)
+ if(iHWState == EInquiry && RequestedInquiryIAC() != iCurrentInquiryIAC)
{
- // If the current IAC is GIAC, and the requested inquiry IAC isn't, it must be LIAC
- __ASSERT_DEBUG(iRequestedInquiryIAC == KLIAC, Panic(EBTUnexpectedIAC));
- // Queue a general inquiry for when the current limited inquiry has finished
- iQueuedInquiryIAC = aIAC;
- return;
- }
- else if(iHWState == EInquiry)
- {
- // The host resolver should only allow through GIAC and LIAC, and we handle GIAC above
- __ASSERT_DEBUG(aIAC == KLIAC, Panic(EBTUnexpectedIAC));
- // We favour a Limited inqiury, so interrupt the current general inquiry
+ // The requested IAC (which prioritises LIAC) is different to the current IAC, so cancel to change the IAC
TInt err = CancelHardwareInquiry();
if(err!=KErrNone)
{
@@ -1566,23 +1558,12 @@
aResolver.InquiryComplete(err); // cancel went wrong
return;
}
- // Queue a general inquiry for when the limited inquiry is complete
- iRequestedInquiryIAC = KLIAC;
- iQueuedInquiryIAC = KGIAC;
SetHWState(ECancellingForNewIAC);
iFlusher->Cancel(); // Stop watchdog, start flusher.
return;
}
- else
- {
- // The host resolver should only allow through GIAC and LIAC, and we handle GIAC above
- __ASSERT_DEBUG(aIAC == KLIAC, Panic(EBTUnexpectedIAC));
- iRequestedInquiryIAC = KLIAC;
- iQueuedInquiryIAC = KGIAC;
- }
}
- iRequestedInquiryIAC = aIAC;
iInquiryInteruptions = 0;
DoInquiry();
@@ -1802,10 +1783,10 @@
{
LOG_FUNC
- if(iRequestedInquiryIAC == 0 || iHWState != EIdle || iHRs.IsEmpty())
+ if(RequestedInquiryIAC() == 0 || iHWState != EIdle || iHRs.IsEmpty())
{
#ifdef _DEBUG
- LOG3(_L("Not starting inquiry. iRequestedInquiryIAC == %d, iHWState == %d, iHostResolverCount == %d"), iRequestedInquiryIAC, iHWState, iNumHRs);
+ LOG3(_L("Not starting inquiry. RequestedInquiryIAC == %d, iHWState == %d, iHostResolverCount == %d"), RequestedInquiryIAC(), iHWState, iNumHRs);
if (iHRs.IsEmpty())
{
LOG(_L("No HRs interested in results - Stopping discovery"));
@@ -1816,6 +1797,10 @@
LOG(_L("CBTInquiryMgr::DoInquiry PublishStatus Idle"));
PublishStatus();// make sure the status says we're idle
}
+ if (RequestedInquiryIAC() == 0)
+ {
+ iCurrentInquiryIAC = 0;
+ }
return;
}
@@ -1845,7 +1830,7 @@
{
// Couldn't start inquiry.
// Make sure the request is completed.
- iRequestedInquiryIAC = 0;
+ iCurrentInquiryIAC = 0;
InquiryComplete(err, 0);
LOG(_L("CBTInquiryMgr::DoInquiry PublishState Idle couldn't start inquiry"));
PublishStatus();
@@ -1877,7 +1862,7 @@
TInt CBTInquiryMgr::StartHardwareInquiry()
{
LOG_FUNC
- iCurrentInquiryIAC = iRequestedInquiryIAC;
+ iCurrentInquiryIAC = RequestedInquiryIAC();
// attempt to free up baseband space for best performance discovery
iLinkMgrProtocol.PhysicalLinksMgr().RequireSlotSpace(); // will *eventually* put connections in hold - we dont wait though
TRAPD(err, StartInquiryL(iCurrentInquiryIAC, KInquiryLength, KInquiryMaxResults));
@@ -1923,8 +1908,7 @@
CBTInqResultRecord& rec = ref->Result();
if(rec.IsNameRequestPending())
{
- if(!iRequestedInquiryIAC ||
- rec.NameLookupAttempts() < KMaxNameLookupAttemptsDuringInquiry)
+ if(RequestedInquiryIAC() == 0 || rec.NameLookupAttempts() < KMaxNameLookupAttemptsDuringInquiry)
{
// We want the first record for the current IAC or a record for an explicit name request.
// Failing that, we'll just have the first record