bluetooth/btstack/linkmgr/physicallinks.cpp
changeset 32 f72906e669b4
parent 31 b9d1744dc449
child 42 206564d58f40
equal deleted inserted replaced
31:b9d1744dc449 32:f72906e669b4
   143 	iAuthenticationCtrl.Abort();
   143 	iAuthenticationCtrl.Abort();
   144 
   144 
   145 	delete iPhysicalLinkMetrics;
   145 	delete iPhysicalLinkMetrics;
   146 	delete iPinRequester;
   146 	delete iPinRequester;
   147 	delete iNumericComparator;
   147 	delete iNumericComparator;
       
   148 	delete iUserConfirmer;
   148 	delete iPasskeyEntry;
   149 	delete iPasskeyEntry;
   149 	delete iArbitrationDelay;
   150 	delete iArbitrationDelay;
   150 	delete iRoleSwitchCompleteCallBack;
   151 	delete iRoleSwitchCompleteCallBack;
   151 	delete iEncryptionEnforcer;
   152 	delete iEncryptionEnforcer;
   152 
   153 
   925 	}
   926 	}
   926 
   927 
   927 void CPhysicalLink::ConnectionComplete(THCIErrorCode aErr, const TBTConnect& aConn)
   928 void CPhysicalLink::ConnectionComplete(THCIErrorCode aErr, const TBTConnect& aConn)
   928 	{
   929 	{
   929 	LOG_FUNC
   930 	LOG_FUNC
   930 	if (aErr == KErrNone)
   931 	ConnectionComplete(CHciUtil::SymbianErrorCode(aErr), aConn);
       
   932 	}
       
   933 
       
   934 void CPhysicalLink::ConnectionComplete(TInt aResult, const TBTConnect& aConn)
       
   935 	{
       
   936 	if (aResult == KErrNone)
   931 		{
   937 		{
   932 		if(aConn.iLinkType == ESCOLink && !iSyncLogicalLink)
   938 		if(aConn.iLinkType == ESCOLink && !iSyncLogicalLink)
   933 			{
   939 			{
   934 			LOG(_L("Got a ConnectionComplete for a non-existant SCO link"))
   940 			LOG(_L("Got a ConnectionComplete for a non-existant SCO link"))
   935 			//This situation can occur if ESock deletes the iSyncLogicalLink whilst it is waiting for
   941 			//This situation can occur if ESock deletes the iSyncLogicalLink whilst it is waiting for
   936 			//a remote device to respond to a connection request.
   942 			//a remote device to respond to a connection request.
   937 			iLinksMan.Baseband().UpdateModelForConnectionError(aConn.iBdaddr, aConn.iLinkType);
   943 			iLinksMan.Baseband().UpdateModelForConnectionError(aConn.iBdaddr, aConn.iLinkType);
   938 
   944 
   939 			if(aErr==EOK) // if error, aConn.iConnH will refer to the ACL link used to initialise the SCO link, so dont disconnect that
   945 			//The baseband might actually have established a SCO link, so send a Disconnect.
   940 				{
   946 			//If no SCO link exists the command will fail gracefully.
   941 				//The baseband might actually have established a SCO link, so send a Disconnect.
   947 			TRAP_IGNORE(iLinksMan.HCIFacade().DisconnectL(aConn.iConnH, ERemoteUserEndedConnection));
   942 				//If no SCO link exists the command will fail gracefully.
       
   943 				TRAP_IGNORE(iLinksMan.HCIFacade().DisconnectL(aConn.iConnH, ERemoteUserEndedConnection));
       
   944 				}
       
   945 
   948 
   946 			return;
   949 			return;
   947 			}
   950 			}
   948 
   951 
   949 		// update bb model
   952 		// update bb model
   987 			NotifyStateChange(event);
   990 			NotifyStateChange(event);
   988 
   991 
   989 			if (aConn.iEncryptMode)
   992 			if (aConn.iEncryptMode)
   990 				{
   993 				{
   991 				// pretend there's been an encryption event
   994 				// pretend there's been an encryption event
   992 				EncryptionChange(aErr, aConn.iConnH, aConn.iEncryptMode);
   995 				EncryptionChange(EOK, aConn.iConnH, aConn.iEncryptMode);
   993 				}
   996 				}
   994 			}
   997 			}
   995 
   998 
   996 		// This is assuming that our stack only allows one synchronous link per phy link.
   999 		// This is assuming that our stack only allows one synchronous link per phy link.
   997  		// SCO (not eSCO) Link getting notified here.
  1000  		// SCO (not eSCO) Link getting notified here.
  1059 			// The KInvalidConnectionHandle test ensures that we ignore errored outgoing SCO connects.
  1062 			// The KInvalidConnectionHandle test ensures that we ignore errored outgoing SCO connects.
  1060 			return;
  1063 			return;
  1061 			}
  1064 			}
  1062 
  1065 
  1063 		iLinksMan.Baseband().UpdateModelForConnectionError(aConn.iBdaddr, aConn.iLinkType);
  1066 		iLinksMan.Baseband().UpdateModelForConnectionError(aConn.iBdaddr, aConn.iLinkType);
  1064 		NotifyLogicalLinkError(aConn.iLinkType, CHciUtil::SymbianErrorCode(aErr));
  1067 		NotifyLogicalLinkError(aConn.iLinkType, aResult);
  1065 		if (aConn.iLinkType == EACLLink)
  1068 		if (aConn.iLinkType == EACLLink)
  1066 			{
  1069 			{
  1067 			// BT 1.2 says that as the ACL Link goes up and down, so does the physical link
  1070 			// BT 1.2 says that as the ACL Link goes up and down, so does the physical link
  1068 			// so if the ACL Link has gone, so has this
  1071 			// so if the ACL Link has gone, so has this
  1069 			// for SCO we remain in place.
  1072 			// for SCO we remain in place.
  1070 			TBTBasebandEventNotification event(ENotifyPhysicalLinkError, CHciUtil::SymbianErrorCode(aErr));
  1073 			TBTBasebandEventNotification event(ENotifyPhysicalLinkError, aResult);
  1071 			NotifyStateChange(event);
  1074 			NotifyStateChange(event);
  1072 			delete this;
  1075 			delete this;
  1073 			}
  1076 			}
  1074 		}
  1077 		}
  1075 	// ***Watchout*** delete this above: careful about code here
  1078 	// ***Watchout*** delete this above: careful about code here
  1698 
  1701 
  1699 TInt CPhysicalLink::Arbitrate(TBool aImmediately, TBool aLocalPriority)
  1702 TInt CPhysicalLink::Arbitrate(TBool aImmediately, TBool aLocalPriority)
  1700 	{
  1703 	{
  1701 	LOG_FUNC
  1704 	LOG_FUNC
  1702 	if (!IsConnected())
  1705 	if (!IsConnected())
       
  1706 		{
       
  1707 		LOG(_L8("Physical link not connected, no arbitration executed"));
  1703 		return KErrDisconnected;
  1708 		return KErrDisconnected;
  1704 
  1709 		}
  1705 	if ( aImmediately )
  1710 	// The arbitration delay object will decide how much delay
  1706 		{
  1711 	return iArbitrationDelay->Start(aImmediately, aLocalPriority);
  1707 		iArbitrationDelay->Cancel();
       
  1708 		return DoArbitrate(aLocalPriority);		
       
  1709 		}
       
  1710 	else if (iArbitrationDelay->IsActive())
       
  1711 		{
       
  1712 		return KErrNone;
       
  1713 		}
       
  1714 	else
       
  1715 		{
       
  1716 		iArbitrationDelay->Start(aLocalPriority);
       
  1717 		return KErrNone;
       
  1718 		}
       
  1719 	}
  1712 	}
  1720 
  1713 
  1721 TInt CPhysicalLink::DoArbitrate(TBool aLocalPriority)
  1714 TInt CPhysicalLink::DoArbitrate(TBool aLocalPriority)
  1722 	{
  1715 	{
       
  1716 	LOG_FUNC
  1723 	if (!IsConnected())
  1717 	if (!IsConnected())
  1724 		{
  1718 		{
       
  1719 		LOG(_L8("Physical link not connected, no arbitration executed"));
  1725 		return KErrDisconnected;
  1720 		return KErrDisconnected;
  1726 		}
  1721 		}
  1727 
  1722 
  1728 	//start arbitrate process with what our local controller supports
  1723 	//start arbitrate process with what our local controller supports
  1729 	TUint8 allowedModesMask = EHoldMode | EParkMode | ESniffMode; // local features sorted out later
  1724 	TUint8 allowedModesMask = EHoldMode | EParkMode | ESniffMode; // local features sorted out later
  1730 	TBool roleSwitchAllowed = EFalse;
  1725 	TBool roleSwitchAllowed = iLinksMan.LinkManagerProtocol().IsRoleSwitchSupportedLocally() && iLinksMan.RoleSwitchAllowed();
  1731 
  1726 	LOG2(_L8("Arbitration: link policy (LPM:0x%02x, Role:0x%x) - Prior to proxies"), allowedModesMask, roleSwitchAllowed);
  1732  	if (iLinksMan.LinkManagerProtocol().IsRoleSwitchSupportedLocally() && iLinksMan.RoleSwitchAllowed())
  1727 	
  1733  		{
       
  1734  		roleSwitchAllowed = ETrue;
       
  1735  		}
       
  1736 
       
  1737 	// ask proxies what they want from the PHY
  1728 	// ask proxies what they want from the PHY
  1738  	TUint8 requestedModeMask = 0;
  1729 	TUint16 requestedModeMask = 0; // mask of current LPM requests from proxy's
  1739  	TUint8 requestedMode = 0;
  1730 	static const TUint16 KExplicitActiveMode = 0x0100; // special bit for explicit active mode requests
  1740  	TBool activeModeIsRequested = EFalse;
  1731 	
  1741 	TSglQueIter<CBTProxySAP> iter(iProxySAPs);
  1732 	TSglQueIter<CBTProxySAP> iter(iProxySAPs);
  1742 	while (iter)
  1733 	while (iter)
  1743 		{
  1734 		{
  1744 		CBTProxySAP* proxy = iter++;
  1735 		CBTProxySAP* proxy = iter++;
  1745 
  1736 
  1746  		requestedMode = proxy->GetRequestedModes();
  1737 		TUint8 requestedMode = proxy->GetRequestedModes();
  1747  		requestedModeMask |= requestedMode;
  1738 		requestedModeMask |= requestedMode;
  1748 
  1739 
  1749 		if (requestedMode == EActiveMode && proxy->RequestedActiveMode())
  1740 		TBool explicitActiveModeRequest = proxy->RequestedActiveMode();
  1750  			{
  1741 		if (requestedMode == EActiveMode && explicitActiveModeRequest)
  1751  			// An Active Mode request will override all other local low power mode requests
  1742 			{
  1752  			// but continue to collect the requirement from the other proxies..
  1743 			requestedModeMask |= KExplicitActiveMode;
  1753  			activeModeIsRequested = ETrue;
  1744 			}
  1754  			}
  1745 
  1755 
  1746 		TUint8 allowedModes = proxy->GetAllowedModes();
  1756 		allowedModesMask &= proxy->GetAllowedModes();
  1747 		allowedModesMask &= allowedModes;
  1757 		roleSwitchAllowed &= proxy->IsRoleSwitchAllowed();
  1748 		
  1758 		}
  1749 		TBool roleSwitchAllowedByProxy = proxy->IsRoleSwitchAllowed();
  1759 
  1750 		roleSwitchAllowed = roleSwitchAllowed && roleSwitchAllowedByProxy;
  1760  	if (activeModeIsRequested)
  1751 		
  1761  		{
  1752 		LOG4(_L8("Arbitration: Proxy(0x%08x) - requested mode = 0x%04x, link policy (LPM:0x%02x, Role:0x%x)"), proxy, requestedMode, allowedModes, roleSwitchAllowedByProxy);
  1762  		// Any Active Mode request will override all other low power mode requests,
  1753 		}
  1763  		// so overwrite the requestedModeMask but keep allowedModesMask and roleSwitchAllowed
  1754 	LOG2(_L8("Arbitration: link policy (LPM:0x%02x, Role:0x%x) - after proxies"), allowedModesMask, roleSwitchAllowed);
  1764  		// as specified by all the local proxies
       
  1765  		requestedModeMask = EActiveMode;
       
  1766  		}
       
  1767 
  1755 
  1768 	// clear out modes not supported by local Controller
  1756 	// clear out modes not supported by local Controller
       
  1757 	// Future improvement - what about modes supported by the remote device?
  1769 	allowedModesMask &= iLinksMan.LinkManagerProtocol().ModesSupportedLocally();
  1758 	allowedModesMask &= iLinksMan.LinkManagerProtocol().ModesSupportedLocally();
       
  1759 	LOG2(_L8("Arbitration: link policy (LPM:0x%02x, Role:0x%x) - only supported modes"), allowedModesMask, roleSwitchAllowed);
  1770 
  1760 
  1771 	if(iOverrideParkRequests)
  1761 	if(iOverrideParkRequests)
  1772 		{
  1762 		{
  1773 		// We wish to ensure the physical link is not in PARK mode.
  1763 		// We wish to ensure the physical link is not in PARK mode.
  1774 		// The only way to guarantee this is to disallow PARK via the link policy settings.
  1764 		// The only way to guarantee this is to disallow PARK via the link policy settings.
  1775 		allowedModesMask &= ~EParkMode;
  1765 		allowedModesMask &= ~EParkMode;
  1776 		}
  1766 		}
  1777 
  1767 	LOG2(_L8("Arbitration: link policy (LPM:0x%02x, Role:0x%x) - overrides applied"), allowedModesMask, roleSwitchAllowed);
  1778 	if(allowedModesMask != iLinkPolicy.LowPowerModePolicy()
  1768 
  1779 		|| roleSwitchAllowed != iLinkPolicy.IsSwitchAllowed())
  1769 	// Controller policy for the connection may need updating
  1780 		{
  1770 	SetModesAllowed(allowedModesMask, roleSwitchAllowed);
  1781 		// Controller policy for the connection needs updating
  1771 	LOG2(_L8("Arbitration: link policy (LPM:0x%02x, Role:0x%x) - submitted"), allowedModesMask, roleSwitchAllowed);
  1782 		SetModesAllowed(allowedModesMask, roleSwitchAllowed);
       
  1783 		}
       
  1784 
  1772 
  1785 	//If OverrideLPM flag is set, we do not disable LP modes via the link policy settings
  1773 	//If OverrideLPM flag is set, we do not disable LP modes via the link policy settings
  1786 	//This is done because OverrideLPM should not prevent remotes putting us into an LPM
  1774 	//This is done because OverrideLPM should not prevent remotes putting us into an LPM
  1787 	//Later on, when OverrideLPM flag is cancelled, it would allow us to enforce requested LPM
  1775 	//Later on, when OverrideLPM flag is cancelled, it would allow us to enforce requested LPM
  1788 	if(iOverrideLPMRequests)
  1776 	if(iOverrideLPMRequests)
  1789 		{
  1777 		{
  1790 		// We need to ensure the physical link is in active mode.
  1778 		// We need to ensure the physical link is in active mode.
  1791 		allowedModesMask = EActiveMode;
  1779 		allowedModesMask = EActiveMode;
  1792 		}
  1780 		}
  1793 
  1781 	LOG2(_L8("Arbitration: link policy (LPM:0x%02x, Role:0x%x) - post setting overrides applied"), allowedModesMask, roleSwitchAllowed);
  1794 	TUint8 modeChangeMask = static_cast<TUint8>(requestedModeMask & allowedModesMask);
  1782 
  1795 	TUint8 modeCompareMask = 0;
  1783 	TUint16 modeChangeMask = requestedModeMask & (static_cast<TUint16>(allowedModesMask)|KExplicitActiveMode);
       
  1784 	TUint16 modeCompareMask = 0;
       
  1785 	LOG2(_L8("Arbitration: mode change mask = 0x%04x, local priority = 0x%x"), modeChangeMask, aLocalPriority);
  1796 
  1786 
  1797 	if(aLocalPriority)
  1787 	if(aLocalPriority)
  1798 		{
  1788 		{
  1799 		// If we want local priority, we go with what we want to do
  1789 		// If we want local priority, we go with what we want to do
  1800 		// irrespective of what the remote may have previously requested.
  1790 		// irrespective of what the remote may have previously requested.
  1807  		// because a remote device has changed it..
  1797  		// because a remote device has changed it..
  1808 
  1798 
  1809 		// modeCompareMask should start only having zero bits where
  1799 		// modeCompareMask should start only having zero bits where
  1810 		// requestedModeMask has a zero bit and iPreviousRequestedModeMask does not
  1800 		// requestedModeMask has a zero bit and iPreviousRequestedModeMask does not
  1811 		// i.e. a mode is newly no longer requested.
  1801 		// i.e. a mode is newly no longer requested.
  1812 		modeCompareMask = requestedModeMask | ~iPreviousRequestedModeMask;
  1802 		modeCompareMask = ~((requestedModeMask ^ iPreviousRequestedModeMask) & iPreviousRequestedModeMask);
  1813 
  1803 
  1814 		// Remove bits from modeCompareMask that are not in allowedModesMask
  1804 		// Remove bits from modeCompareMask that are not in allowedModesMask
  1815 		// We cannot stay in a power mode that we do not allow.
  1805 		// We cannot stay in a power mode that we do not allow.
  1816 		modeCompareMask &= allowedModesMask;
  1806 		modeCompareMask &= (static_cast<TUint16>(allowedModesMask)|KExplicitActiveMode);
  1817 		}
  1807 		}
       
  1808 	LOG1(_L8("Arbitration: Comparison mask = 0x%04x"), modeCompareMask);
  1818 
  1809 
  1819 	iPreviousRequestedModeMask = requestedModeMask; // Update previous requested to current value.
  1810 	iPreviousRequestedModeMask = requestedModeMask; // Update previous requested to current value.
  1820 
  1811 
  1821 	TUint8 currentModeMask = static_cast<TUint8>(iLinkState.LinkMode());
  1812 	// get the current mode.
       
  1813 	TBTLinkMode currentMode = iLinkState.LinkMode();
       
  1814 	TUint16 currentModeMask = static_cast<TUint16>(currentMode);
       
  1815 	if(currentModeMask == EActiveMode)
       
  1816 		{
       
  1817 		// if in active mode then could have been because of an explicit active mode request
       
  1818 		currentModeMask |= KExplicitActiveMode;
       
  1819 		}
       
  1820 	LOG1(_L8("Arbitration: Current mode mask = 0x%04x"), currentModeMask);
       
  1821 	
  1822 	if(modeCompareMask & currentModeMask)
  1822 	if(modeCompareMask & currentModeMask)
  1823 		{
  1823 		{
       
  1824 		LOG2(_L8("Arbitration: Comparison mask (0x%04x) matched, so staying in current mode (0x%04x)"), modeCompareMask, currentModeMask);
  1824 		// The current state is the same as the permitted required role(s).
  1825 		// The current state is the same as the permitted required role(s).
  1825 		return KErrNone;
  1826 		return KErrNone;
  1826 		}
  1827 		}
  1827 
  1828 	
  1828 	if(modeChangeMask == EActiveMode && currentModeMask != EActiveMode)
  1829 	TBTLinkMode nextMode = EActiveMode;
  1829 		{
  1830 	// Determine which LPM we should be in (if any)
  1830 		// The current low power mode should be exited.
  1831 	if(modeChangeMask & KExplicitActiveMode)
  1831 		return RequestActive();
  1832 		{
  1832 		}
  1833 		nextMode = EActiveMode;
  1833 
  1834 		}
  1834 	if(modeChangeMask != EActiveMode)
  1835 	else if(modeChangeMask & EHoldMode)
  1835 		{
  1836 		{
  1836 		if(currentModeMask != EActiveMode)
  1837 		nextMode = EHoldMode;
  1837 			{
  1838 		}
  1838 			// The system is currently in a low power mode.  Exit this before
  1839 	else if(modeChangeMask & ESniffMode)
  1839 			// entering the new mode.
  1840 		{
  1840 			TInt rerr = RequestActive();
  1841 		nextMode = ESniffMode;
  1841 			if(rerr != KErrNone)
  1842 		}
       
  1843 	else if(modeChangeMask & EParkMode)
       
  1844 		{
       
  1845 		nextMode = EParkMode;
       
  1846 		}
       
  1847 	LOG2(_L8("Arbitration: Arbitrating mode 0x%02x -> 0x%02x"), currentMode, nextMode);
       
  1848 	
       
  1849 	if(nextMode != currentMode)
       
  1850 		{
       
  1851 		if(currentMode != EActiveMode)
       
  1852 			{
       
  1853 			LOG(_L8("Arbitration: Exiting existing LPM mode..."));
       
  1854 			TInt err = RequestActive();
       
  1855 			if(err != KErrNone)
  1842 				{
  1856 				{
  1843 				return rerr;
  1857 				return err;
  1844 				}
  1858 				}
  1845 			}
  1859 			}
  1846 
  1860 		if(nextMode == EHoldMode)
  1847 		if(modeChangeMask & EHoldMode)
  1861 			{
  1848 			{
  1862 			LOG(_L8("Arbitration: Entering Hold mode..."));
  1849 			return RequestHold();
  1863 			return RequestHold();
  1850 			}
  1864 			}
  1851 		if(modeChangeMask & ESniffMode)
  1865 		else if(nextMode == ESniffMode)
  1852 			{
  1866 			{
       
  1867 			LOG(_L8("Arbitration: Entering Sniff mode..."));
  1853 			return RequestSniff();
  1868 			return RequestSniff();
  1854 			}
  1869 			}
  1855 		if(modeChangeMask & EParkMode)
  1870 		else if(nextMode == EParkMode)
  1856 			{
  1871 			{
       
  1872 			LOG(_L8("Arbitration: Entering Park mode..."));
  1857 			return RequestPark();
  1873 			return RequestPark();
  1858 			}
  1874 			}
  1859 		}
  1875 		else if(nextMode == EActiveMode)
  1860 
  1876 			{
  1861 	// This point in the code is reached if the Link Policy settings are
  1877 			LOG(_L8("Arbitration: Staying in Active mode..."));
  1862 	// changed but the mode is not.	 Return OK error code.
  1878 			return KErrNone;
       
  1879 			}
       
  1880 		// Shouldn't reach here, we have a strange mode
       
  1881 		DEBUG_PANIC_LINENUM;
       
  1882 		}
       
  1883 
       
  1884 	LOG(_L8("Arbitration: Already in correct LPM, not doing anything"));
  1863 	return KErrNone;
  1885 	return KErrNone;
  1864 	}
  1886 	}
  1865 
  1887 
  1866 void CPhysicalLink::SetPassKey(const TDesC8& aPassKey)
  1888 void CPhysicalLink::SetPassKey(const TDesC8& aPassKey)
  1867 	{
  1889 	{
  1878 	}
  1900 	}
  1879 
  1901 
  1880 void CPhysicalLink::StartArbitrationTimer() const
  1902 void CPhysicalLink::StartArbitrationTimer() const
  1881 	{
  1903 	{
  1882 	LOG_FUNC
  1904 	LOG_FUNC
  1883 	iArbitrationDelay->Start();
  1905 	iArbitrationDelay->Restart();
  1884 	}
  1906 	}
  1885 
  1907 
  1886 TInt CPhysicalLink::Connect(TBasebandPageTimePolicy aPolicy)
  1908 void CPhysicalLink::Connect(TBasebandPageTimePolicy aPolicy)
  1887 	{
  1909 	{
  1888 	LOG_FUNC
  1910 	LOG_FUNC
  1889 	// assume that we will be master until told otherwise
  1911 	// assume that we will be master until told otherwise
  1890 	ASSERT_DEBUG(!IsConnected());
  1912 	ASSERT_DEBUG(!IsConnected());
  1891 
  1913 
  1900 	TUint16 pkt = KHCIDefaultPacketType;
  1922 	TUint16 pkt = KHCIDefaultPacketType;
  1901 
  1923 
  1902 	// optimise paging (as a best-effort attempt).
  1924 	// optimise paging (as a best-effort attempt).
  1903 	TBasebandTime pagetimeout = CalculatePageTimeout(aPolicy, psrm, clockOffset & KHCIClockOffsetValidBit);
  1925 	TBasebandTime pagetimeout = CalculatePageTimeout(aPolicy, psrm, clockOffset & KHCIClockOffsetValidBit);
  1904 	iLinksMan.TryToChangePageTimeout(pagetimeout);
  1926 	iLinksMan.TryToChangePageTimeout(pagetimeout);
       
  1927 	
       
  1928 	// Set state in anticipation of the connection
       
  1929 	iLinkState.SetLinkState(TBTBasebandLinkState::ELinkPending);
       
  1930 	iLinksMan.Baseband().UpdateModel(iDevice.Address(), pkt, EACLLink);
       
  1931 	iLinkState.SetLinkRole(EMaster);
  1905 
  1932 
  1906 	TRAPD(ret, iLinksMan.HCIFacade().ConnectL(iDevice.Address(), pkt, psrm, psm, clockOffset, allowRoleSwitch));
  1933 	TRAPD(ret, iLinksMan.HCIFacade().ConnectL(iDevice.Address(), pkt, psrm, psm, clockOffset, allowRoleSwitch));
  1907 	if(ret==KErrNone)
  1934 	if(ret != KErrNone) // a physical link is in charge of it's own destiny.
  1908 		{
  1935 		{
  1909 		iLinkState.SetLinkState(TBTBasebandLinkState::ELinkPending);
  1936 		TBTConnect conn;
  1910 		iLinksMan.Baseband().UpdateModel(iDevice.Address(), pkt, EACLLink);
  1937 		conn.iBdaddr = BDAddr();
  1911 		iLinkState.SetLinkRole(EMaster);
  1938 		conn.iLinkType = EACLLink;
  1912 		}
  1939 		ConnectionComplete(ret, conn);
  1913 
  1940 		}
  1914 	return ret;
       
  1915 	}
  1941 	}
  1916 
  1942 
  1917 TInt CPhysicalLink::SCOConnect()
  1943 TInt CPhysicalLink::SCOConnect()
  1918 /**
  1944 /**
  1919 	A utility service provided to the SCO transport
  1945 	A utility service provided to the SCO transport
  2262 		(aEvent.EventType() & ENotifySniffMode)||
  2288 		(aEvent.EventType() & ENotifySniffMode)||
  2263 		(aEvent.EventType() & ENotifyParkMode)||
  2289 		(aEvent.EventType() & ENotifyParkMode)||
  2264 		(aEvent.EventType() & ENotifyHoldMode)) &&
  2290 		(aEvent.EventType() & ENotifyHoldMode)) &&
  2265 		(aEvent.ErrorCode() == KErrNone))
  2291 		(aEvent.ErrorCode() == KErrNone))
  2266 		{
  2292 		{
  2267 		iArbitrationDelay->Start();
  2293 		iArbitrationDelay->Restart();
  2268 		}
  2294 		}
  2269 	}
  2295 	}
  2270 
  2296 
  2271 /*static*/ TInt CPhysicalLink::TerminateCallback(TAny* aCPhysicalLink)
  2297 /*static*/ TInt CPhysicalLink::TerminateCallback(TAny* aCPhysicalLink)
  2272 	{
  2298 	{
  3376 	}
  3402 	}
  3377 
  3403 
  3378 // CArbitrationDelayTimer
  3404 // CArbitrationDelayTimer
  3379 
  3405 
  3380 CArbitrationDelayTimer::CArbitrationDelayTimer(CPhysicalLink* aParent)
  3406 CArbitrationDelayTimer::CArbitrationDelayTimer(CPhysicalLink* aParent)
  3381 	:CTimer(CActive::EPriorityStandard),
  3407 	: CTimer(CActive::EPriorityStandard)
  3382 	iParent(aParent)
  3408 	, iParent(aParent)
  3383 	{
  3409 	{
  3384 	LOG_FUNC
  3410 	LOG_FUNC
       
  3411 	ASSERT_DEBUG(iParent);
       
  3412 	CActiveScheduler::Add(this);
  3385 	}
  3413 	}
  3386 
  3414 
  3387 void CArbitrationDelayTimer::ConstructL()
  3415 void CArbitrationDelayTimer::ConstructL()
  3388 	{
  3416 	{
  3389 	LOG_FUNC
  3417 	LOG_FUNC
  3390 	CTimer::ConstructL();
  3418 	CTimer::ConstructL();
  3391 	CActiveScheduler::Add(this);
       
  3392 	}
  3419 	}
  3393 
  3420 
  3394 CArbitrationDelayTimer* CArbitrationDelayTimer::NewL(CPhysicalLink* aParent)
  3421 CArbitrationDelayTimer* CArbitrationDelayTimer::NewL(CPhysicalLink* aParent)
  3395 	{
  3422 	{
  3396 	LOG_STATIC_FUNC
  3423 	LOG_STATIC_FUNC
  3399 	self->ConstructL();
  3426 	self->ConstructL();
  3400 	CleanupStack::Pop(self);
  3427 	CleanupStack::Pop(self);
  3401 	return self;
  3428 	return self;
  3402 	}
  3429 	}
  3403 
  3430 
  3404 void CArbitrationDelayTimer::Start(TBool aLocalPriority)
  3431 TInt CArbitrationDelayTimer::Start(TBool aImmediate, TBool aLocalPriority)
  3405 	{
  3432 	{
  3406 	LOG_FUNC
  3433 	LOG_FUNC
  3407 	// Work out what the local priority will be now
  3434 	// Work out what the local priority will be now
  3408 	TBool localPriority = iLocalPriority || aLocalPriority;
  3435 	iLocalPriority = iLocalPriority || aLocalPriority;
  3409 	Cancel(); // cancel current timer (will also reset priority so ...
  3436 	LOG1(_L8("Arbitraion: Local Priority now %d"), iLocalPriority);
  3410 	iLocalPriority = localPriority; // set the new priority)
  3437 	if(aImmediate)
       
  3438 		{
       
  3439 		LOG(_L8("Arbitraion: Immediate Arbitration Requested..."));
       
  3440 		CancelButPreserveLocalPriority();
       
  3441 		return DoArbitrate();
       
  3442 		}
       
  3443 	else if(!IsActive())
       
  3444 		{
       
  3445 		LOG(_L8("Arbitraion: Arbitration requested, will execute after delay timer..."));
       
  3446 		After(KBTArbitrationDelay);
       
  3447 		}
       
  3448 	else // timer is already on its way
       
  3449 		{
       
  3450 		LOG(_L8("Arbitraion: Arbitration delay timer still pending..."));
       
  3451 		}
       
  3452 	return KErrNone;
       
  3453 	}
       
  3454 
       
  3455 void CArbitrationDelayTimer::Restart()
       
  3456 	{
       
  3457 	LOG_FUNC
       
  3458 	LOG(_L8("Arbitraion: Arbitration timer restarted..."));
       
  3459 	CancelButPreserveLocalPriority();
  3411 	After(KBTArbitrationDelay);
  3460 	After(KBTArbitrationDelay);
       
  3461 	}
       
  3462 
       
  3463 void CArbitrationDelayTimer::CancelButPreserveLocalPriority()
       
  3464 	{
       
  3465 	LOG_FUNC
       
  3466 	TBool localPriority = iLocalPriority;
       
  3467 	Cancel();
       
  3468 	iLocalPriority = localPriority;
  3412 	}
  3469 	}
  3413 
  3470 
  3414 
  3471 
  3415 void CArbitrationDelayTimer::RunL()
  3472 void CArbitrationDelayTimer::RunL()
  3416 /**
  3473 /**
  3417 Allow arbitration of low power modes when the timer expires
  3474 Allow arbitration of low power modes when the timer expires
  3418 **/
  3475 **/
  3419 	{
  3476 	{
  3420 	LOG_FUNC
  3477 	LOG_FUNC
  3421 	if (iParent)
  3478 	LOG(_L8("Arbitraion: Delayed Arbitration executing..."));
  3422 		{
  3479 	static_cast<void>(DoArbitrate()); // ignore the error (always has been...)
  3423 		iParent->DoArbitrate(iLocalPriority);
  3480 	}
  3424 		}
  3481 
       
  3482 TInt CArbitrationDelayTimer::DoArbitrate()
       
  3483 	{
       
  3484 	LOG_FUNC
       
  3485 	TBool localPriority = iLocalPriority;
       
  3486 	iLocalPriority = EFalse;
       
  3487 	return iParent->DoArbitrate(localPriority);
  3425 	}
  3488 	}
  3426 
  3489 
  3427 void CArbitrationDelayTimer::DoCancel()
  3490 void CArbitrationDelayTimer::DoCancel()
  3428 	{
  3491 	{
  3429 	LOG_FUNC
  3492 	LOG_FUNC