23 #include "SCOSAP.h" |
23 #include "SCOSAP.h" |
24 #include "ProxySAP.h" |
24 #include "ProxySAP.h" |
25 #include "linkconsts.h" |
25 #include "linkconsts.h" |
26 #include "hcifacade.h" |
26 #include "hcifacade.h" |
27 #include "hostresolver.h" |
27 #include "hostresolver.h" |
28 #include "roleswitchhelper.h" |
28 #include "PhysicalLinkHelper.h" |
29 #include "pairingscache.h" |
29 #include "pairingscache.h" |
30 #include "oobdata.h" |
30 #include "oobdata.h" |
31 #include "pairingserver.h" |
31 #include "pairingserver.h" |
32 #include "encryptionkeyrefreshhelper.h" |
|
33 |
32 |
34 #include <bt_sock.h> |
33 #include <bt_sock.h> |
35 |
34 |
36 #include <bluetooth/hci/commandstatusevent.h> |
35 #include <bluetooth/hci/commandstatusevent.h> |
37 #include <bluetooth/hci/sniffmodecommand.h> |
36 #include <bluetooth/hci/sniffmodecommand.h> |
57 #endif |
56 #endif |
58 |
57 |
59 static const THCIErrorCode KDefaultRejectReason = EHostSecurityRejection; // see spec Error Codes |
58 static const THCIErrorCode KDefaultRejectReason = EHostSecurityRejection; // see spec Error Codes |
60 |
59 |
61 #ifdef _DEBUG |
60 #ifdef _DEBUG |
62 #define __CHECK_CONNECTION_HANDLE(aHandle) __ASSERT_DEBUG(HasHandle(aHandle), Panic(EBTLinkMgrConnectionEventInWrongSAP)); |
61 #define __CHECK_CONNECTION_HANDLE(aHandle) __ASSERT_DEBUG(aHandle==iHandle, Panic(EBTLinkMgrConnectionEventInWrongSAP)); |
63 #else |
62 #else |
64 #define __CHECK_CONNECTION_HANDLE(aHandle) aHandle=aHandle; // to suppress warnings |
63 #define __CHECK_CONNECTION_HANDLE(aHandle) aHandle=aHandle; // to suppress warnings |
65 #endif |
64 #endif |
66 |
65 |
67 CPhysicalLink* CPhysicalLink::NewLC(CPhysicalLinksManager& aConnectionMan, CRegistrySession& aRegSess, const TBTNamelessDevice& aDevice) |
66 CPhysicalLink* CPhysicalLink::NewLC(CPhysicalLinksManager& aConnectionMan, CRegistrySession& aRegSess, const TBTNamelessDevice& aDevice) |
90 , iDeviceResult(KDeviceNotObtained) |
89 , iDeviceResult(KDeviceNotObtained) |
91 , iRegistryHelpers(_FOFF(CBTRegistryHelperBase,iLink)) |
90 , iRegistryHelpers(_FOFF(CBTRegistryHelperBase,iLink)) |
92 , iProxySAPs(_FOFF(CBTProxySAP, iQueueLink)) |
91 , iProxySAPs(_FOFF(CBTProxySAP, iQueueLink)) |
93 , iOverrideParkRequests(EFalse) |
92 , iOverrideParkRequests(EFalse) |
94 , iOverrideLPMRequests(EFalse) |
93 , iOverrideLPMRequests(EFalse) |
|
94 , iLPMOverrideTimerQueued(EFalse) |
95 , iConnectionPacketTypeChanged(EFalse) |
95 , iConnectionPacketTypeChanged(EFalse) |
96 , iLowPowModeCtrl(*this, iLinksMan.HCIFacade().CommandQController()) |
96 , iLowPowModeCtrl(*this, iLinksMan.HCIFacade().CommandQController()) |
97 , iDisconnectCtrl(*this, iLinksMan.HCIFacade().CommandQController()) |
97 , iDisconnectCtrl(*this, iLinksMan.HCIFacade().CommandQController()) |
98 , iAuthenticationCtrl(*this, iLinksMan.HCIFacade().CommandQController()) |
98 , iAuthenticationCtrl(*this, iLinksMan.HCIFacade().CommandQController()) |
99 , iLSTO(0) |
99 , iLSTO(0) |
117 // tell ConnectionsManager... |
117 // tell ConnectionsManager... |
118 iLinksMan.RemovePhysicalLink(*this); |
118 iLinksMan.RemovePhysicalLink(*this); |
119 iACLLogicalLinks.Close(); |
119 iACLLogicalLinks.Close(); |
120 |
120 |
121 RemoveIdleTimer(); |
121 RemoveIdleTimer(); |
|
122 if (iLPMOverrideTimerQueued) |
|
123 { |
|
124 BTSocketTimer::Remove(iOverrideLPMTimerEntry); |
|
125 iLPMOverrideTimerQueued = EFalse; |
|
126 } |
122 |
127 |
123 LOG(_L("sec\tClosing subscribers...")) |
128 LOG(_L("sec\tClosing subscribers...")) |
124 |
129 |
125 LOG(_L("sec\tClosing helpers...")) |
130 LOG(_L("sec\tClosing helpers...")) |
126 TSglQueIter<CBTRegistryHelperBase> iter(iRegistryHelpers); |
131 TSglQueIter<CBTRegistryHelperBase> iter(iRegistryHelpers); |
142 delete iNumericComparator; |
147 delete iNumericComparator; |
143 delete iUserConfirmer; |
148 delete iUserConfirmer; |
144 delete iPasskeyEntry; |
149 delete iPasskeyEntry; |
145 delete iArbitrationDelay; |
150 delete iArbitrationDelay; |
146 delete iRoleSwitchCompleteCallBack; |
151 delete iRoleSwitchCompleteCallBack; |
147 delete iKeyRefreshCompleteCallBack; |
|
148 delete iEncryptionEnforcer; |
152 delete iEncryptionEnforcer; |
149 |
153 |
150 DeleteRoleSwitcher(); |
154 DeleteRoleSwitcher(); |
151 DeleteKeyRefresher(); |
|
152 } |
155 } |
153 |
156 |
154 void CPhysicalLink::ConstructL() |
157 void CPhysicalLink::ConstructL() |
155 { |
158 { |
156 LOG_FUNC |
159 LOG_FUNC |
159 iArbitrationDelay = CArbitrationDelayTimer::NewL(this); |
162 iArbitrationDelay = CArbitrationDelayTimer::NewL(this); |
160 |
163 |
161 TCallBack cb1(RoleSwitchCompleteCallBack, this); |
164 TCallBack cb1(RoleSwitchCompleteCallBack, this); |
162 iRoleSwitchCompleteCallBack = new (ELeave)CAsyncCallBack(cb1, EActiveHighPriority); |
165 iRoleSwitchCompleteCallBack = new (ELeave)CAsyncCallBack(cb1, EActiveHighPriority); |
163 |
166 |
164 TCallBack cb2(KeyRefreshCompleteCallBack, this); |
167 TCallBack cb2(OverrideLPMTimeoutCallback, this); |
165 iKeyRefreshCompleteCallBack = new (ELeave)CAsyncCallBack(cb2, EActiveHighPriority); |
168 iOverrideLPMTimerEntry.Set(cb2); |
166 |
169 |
167 iPhysicalLinkMetrics = CPhysicalLinkMetrics::NewL(*this, iLinksMan.HCIFacade().CommandQController()); |
170 iPhysicalLinkMetrics = CPhysicalLinkMetrics::NewL(*this, iLinksMan.HCIFacade().CommandQController()); |
168 } |
171 } |
169 |
172 |
170 TBool CPhysicalLink::HasHandle(THCIConnHandle aHandle) const |
173 TBool CPhysicalLink::HasHandle(THCIConnHandle aHandle) const |
171 { |
174 { |
217 } |
220 } |
218 |
221 |
219 TInt CPhysicalLink::TryToAndThenPreventHostEncryptionKeyRefresh(TAny* aOutToken) |
222 TInt CPhysicalLink::TryToAndThenPreventHostEncryptionKeyRefresh(TAny* aOutToken) |
220 { |
223 { |
221 LOG_FUNC |
224 LOG_FUNC |
222 TInt err = KErrNone; |
225 // Currently the host encryption key refresh functionality is not supported |
223 // The handling of the TAny* parameter seems a bit wacky - but it makes sense as follows |
226 // as to work smoothly it relies on changes to disable low power modes that |
224 // this call handles a call from the bluetooth control plane (which passes |
227 // are not present in this codeline. |
225 // only a TAny* as a parameter). We need to return a value back through as well, so we need |
228 *reinterpret_cast<MBluetoothControlPlaneToken**>(aOutToken) = NULL; |
226 // a pointer to a pointer (so after using the input it can be modified to point to the |
229 return KErrNotSupported; |
227 // output). We need a Bluetooth device address so a pointer to a pointer to a TBTDevAddr |
|
228 // is passed down. Then the pointer to a pointer is used to update the pointer to a control |
|
229 // plane token (which represents a handle preventing host encryption key refreshes). |
|
230 if (!IsEncryptionPauseResumeSupported()) |
|
231 { |
|
232 err = KErrNotSupported; |
|
233 *reinterpret_cast<MBluetoothControlPlaneToken**>(aOutToken) = NULL; |
|
234 } |
|
235 else |
|
236 { |
|
237 // Only refresh the key if no-one is preventing it and we aren't still |
|
238 // refreshing the key from a previous request. Note that although |
|
239 // the previous key refresh may actually have finished if the key |
|
240 // refresher is waiting for async delete we have only just refreshed |
|
241 // the key and there's no point doing it again. |
|
242 if (iAutoKeyRefreshQue.IsEmpty() && !iKeyRefresher) |
|
243 { |
|
244 TRAPD(err, iKeyRefresher = CEncryptionKeyRefresher::NewL(iLinksMan, *this)); |
|
245 if(!err) |
|
246 { |
|
247 // Kick off the helper state machine |
|
248 iKeyRefresher->StartHelper(); |
|
249 } |
|
250 // If we can't refresh the encryption key, there's not much we can do |
|
251 } |
|
252 XAutoKeyRefreshToken* token = new XAutoKeyRefreshToken(); |
|
253 if (token) |
|
254 { |
|
255 iAutoKeyRefreshQue.AddLast(*token); |
|
256 } |
|
257 else |
|
258 { |
|
259 err = KErrNoMemory; |
|
260 } |
|
261 *reinterpret_cast<MBluetoothControlPlaneToken**>(aOutToken) = token; |
|
262 } |
|
263 return err; |
|
264 } |
230 } |
265 |
231 |
266 void CPhysicalLink::RegistryTaskComplete(CBTRegistryHelperBase* aHelper, TInt /*aResult*/) |
232 void CPhysicalLink::RegistryTaskComplete(CBTRegistryHelperBase* aHelper, TInt /*aResult*/) |
267 /** |
233 /** |
268 A task has completed where we don't expect a response - just cleanup helper |
234 A task has completed where we don't expect a response - just cleanup helper |
1367 { |
1333 { |
1368 LOG_FUNC |
1334 LOG_FUNC |
1369 CBTDeviceNameChanger* nameChanger = CBTDeviceNameChanger::NewL(iRegSess, *this); |
1335 CBTDeviceNameChanger* nameChanger = CBTDeviceNameChanger::NewL(iRegSess, *this); |
1370 iRegistryHelpers.AddLast(*nameChanger); |
1336 iRegistryHelpers.AddLast(*nameChanger); |
1371 nameChanger->Start(BDAddr(), aName); |
1337 nameChanger->Start(BDAddr(), aName); |
1372 } |
|
1373 |
|
1374 void CPhysicalLink::EncryptionKeyRefreshComplete(THCIErrorCode aErr, THCIConnHandle aConnH) |
|
1375 { |
|
1376 LOG_FUNC |
|
1377 __CHECK_CONNECTION_HANDLE(aConnH); |
|
1378 |
|
1379 if(iKeyRefresher) |
|
1380 { |
|
1381 iKeyRefresher->EncryptionKeyRefreshComplete(aErr); |
|
1382 } |
|
1383 } |
1338 } |
1384 |
1339 |
1385 void CPhysicalLink::Disconnection(THCIErrorCode aErr, THCIConnHandle aConnH, THCIErrorCode aResult) |
1340 void CPhysicalLink::Disconnection(THCIErrorCode aErr, THCIConnHandle aConnH, THCIErrorCode aResult) |
1386 { |
1341 { |
1387 LOG_FUNC |
1342 LOG_FUNC |
1842 LOG2(_L8("Arbitration: Comparison mask (0x%04x) matched, so staying in current mode (0x%04x)"), modeCompareMask, currentModeMask); |
1797 LOG2(_L8("Arbitration: Comparison mask (0x%04x) matched, so staying in current mode (0x%04x)"), modeCompareMask, currentModeMask); |
1843 // The current state is the same as the permitted required role(s). |
1798 // The current state is the same as the permitted required role(s). |
1844 return KErrNone; |
1799 return KErrNone; |
1845 } |
1800 } |
1846 |
1801 |
1847 TBTLinkMode targetMode = EActiveMode; |
1802 TBTLinkMode nextMode = EActiveMode; |
1848 // Determine which LPM we should be in (if any) |
1803 // Determine which LPM we should be in (if any) |
1849 if(modeChangeMask & KExplicitActiveMode) |
1804 if(modeChangeMask & KExplicitActiveMode) |
1850 { |
1805 { |
1851 targetMode = EActiveMode; |
1806 nextMode = EActiveMode; |
1852 } |
1807 } |
1853 else if(modeChangeMask & EHoldMode) |
1808 else if(modeChangeMask & EHoldMode) |
1854 { |
1809 { |
1855 targetMode = EHoldMode; |
1810 nextMode = EHoldMode; |
1856 } |
1811 } |
1857 else if(modeChangeMask & ESniffMode) |
1812 else if(modeChangeMask & ESniffMode) |
1858 { |
1813 { |
1859 targetMode = ESniffMode; |
1814 nextMode = ESniffMode; |
1860 } |
1815 } |
1861 else if(modeChangeMask & EParkMode) |
1816 else if(modeChangeMask & EParkMode) |
1862 { |
1817 { |
1863 targetMode = EParkMode; |
1818 nextMode = EParkMode; |
1864 } |
1819 } |
1865 LOG2(_L8("Arbitration: Arbitrating mode 0x%02x -> 0x%02x"), currentMode, targetMode); |
1820 LOG2(_L8("Arbitration: Arbitrating mode 0x%02x -> 0x%02x"), currentMode, nextMode); |
1866 |
1821 |
1867 if(IsConnected()) |
1822 if(nextMode != currentMode) |
1868 { |
1823 { |
1869 TInt err = iLowPowModeCtrl.ExecuteModeChange(targetMode); |
1824 if(currentMode != EActiveMode) |
1870 LOG1(_L8("Arbitration: iLowPowModeCtrl.ExecuteModeChange: err:%d"), err); |
1825 { |
1871 return err; |
1826 LOG(_L8("Arbitration: Exiting existing LPM mode...")); |
1872 } |
1827 TInt err = RequestActive(); |
1873 else |
1828 if(err != KErrNone) |
1874 { |
1829 { |
1875 return KErrDisconnected; |
1830 return err; |
1876 } |
1831 } |
|
1832 } |
|
1833 if(nextMode == EHoldMode) |
|
1834 { |
|
1835 LOG(_L8("Arbitration: Entering Hold mode...")); |
|
1836 return RequestHold(); |
|
1837 } |
|
1838 else if(nextMode == ESniffMode) |
|
1839 { |
|
1840 LOG(_L8("Arbitration: Entering Sniff mode...")); |
|
1841 return RequestSniff(); |
|
1842 } |
|
1843 else if(nextMode == EParkMode) |
|
1844 { |
|
1845 LOG(_L8("Arbitration: Entering Park mode...")); |
|
1846 return RequestPark(); |
|
1847 } |
|
1848 else if(nextMode == EActiveMode) |
|
1849 { |
|
1850 LOG(_L8("Arbitration: Staying in Active mode...")); |
|
1851 return KErrNone; |
|
1852 } |
|
1853 // Shouldn't reach here, we have a strange mode |
|
1854 DEBUG_PANIC_LINENUM; |
|
1855 } |
|
1856 |
|
1857 LOG(_L8("Arbitration: Already in correct LPM, not doing anything")); |
|
1858 return KErrNone; |
1877 } |
1859 } |
1878 |
1860 |
1879 void CPhysicalLink::SetPassKey(const TDesC8& aPassKey) |
1861 void CPhysicalLink::SetPassKey(const TDesC8& aPassKey) |
1880 { |
1862 { |
1881 LOG_FUNC |
1863 LOG_FUNC |
2243 } |
2225 } |
2244 BTSocketTimer::Remove(iIdleTimerEntry); |
2226 BTSocketTimer::Remove(iIdleTimerEntry); |
2245 iIdleTimerQueued = EFalse; |
2227 iIdleTimerQueued = EFalse; |
2246 } |
2228 } |
2247 |
2229 |
|
2230 void CPhysicalLink::QueueLPMOverrideTimer(TInt aTimeout) |
|
2231 /** |
|
2232 Queue LPM Override timer entry. |
|
2233 When this timer expires, it'll call UndoLPMOverride. |
|
2234 **/ |
|
2235 { |
|
2236 LOG_FUNC |
|
2237 __ASSERT_DEBUG(aTimeout!=0, Panic(EBTPhysicalLinksInvalidArgument)); |
|
2238 if (iLPMOverrideTimerQueued) |
|
2239 { |
|
2240 BTSocketTimer::Remove(iOverrideLPMTimerEntry); |
|
2241 } |
|
2242 BTSocketTimer::Queue(aTimeout, iOverrideLPMTimerEntry); |
|
2243 iLPMOverrideTimerQueued = ETrue; |
|
2244 } |
|
2245 |
2248 void CPhysicalLink::NotifyStateChange(TBTBasebandEventNotification& aEvent) |
2246 void CPhysicalLink::NotifyStateChange(TBTBasebandEventNotification& aEvent) |
2249 { |
2247 { |
2250 LOG_FUNC |
2248 LOG_FUNC |
2251 // If this event is 'physical link down' / 'physical link error' then any ProxySAP |
2249 // If this event is 'physical link down' / 'physical link error' then any ProxySAP |
2252 // subscribers will unsubscribe as a result of PhysicalLinkChange being called. |
2250 // subscribers will unsubscribe as a result of PhysicalLinkChange being called. |
2586 } |
2584 } |
2587 |
2585 |
2588 return rerr; |
2586 return rerr; |
2589 } |
2587 } |
2590 |
2588 |
|
2589 TInt CPhysicalLink::ExitMode(TBTLinkMode aMode) |
|
2590 { |
|
2591 LOG_FUNC |
|
2592 return iLowPowModeCtrl.ExitMode(aMode, iHandle); |
|
2593 } |
|
2594 |
|
2595 TInt CPhysicalLink::RequestMode(TBTLinkMode aMode) |
|
2596 { |
|
2597 LOG_FUNC |
|
2598 if (!IsConnected()) |
|
2599 return KErrDisconnected; |
|
2600 |
|
2601 // if active mode is required, try to exit whatever Low Power mode we are in - |
|
2602 // if neither sniff nor park nothing will happen. |
|
2603 if(aMode == EActiveMode) |
|
2604 { |
|
2605 return ExitMode(iLinkState.LinkMode()); |
|
2606 } |
|
2607 |
|
2608 // now request this connection goes to requested mode |
|
2609 return iLowPowModeCtrl.ChangeMode(aMode, iHandle); |
|
2610 } |
|
2611 |
2591 TInt CPhysicalLink::RequestChangeRole(TBTBasebandRole aRole) |
2612 TInt CPhysicalLink::RequestChangeRole(TBTBasebandRole aRole) |
2592 { |
2613 { |
2593 LOG_FUNC |
2614 LOG_FUNC |
2594 TInt err = KErrNone; |
2615 TInt err = KErrNone; |
2595 |
2616 |
2664 LOG_FUNC |
2685 LOG_FUNC |
2665 delete iRoleSwitcher; |
2686 delete iRoleSwitcher; |
2666 iRoleSwitcher = NULL; |
2687 iRoleSwitcher = NULL; |
2667 } |
2688 } |
2668 |
2689 |
2669 void CPhysicalLink::AsyncDeleteKeyRefresher() |
|
2670 { |
|
2671 LOG_FUNC |
|
2672 iKeyRefreshCompleteCallBack->CallBack(); |
|
2673 } |
|
2674 |
|
2675 /*static*/ TInt CPhysicalLink::KeyRefreshCompleteCallBack(TAny* aPhysicalLink) |
|
2676 { |
|
2677 LOG_STATIC_FUNC |
|
2678 CPhysicalLink* physicalLink = static_cast<CPhysicalLink*>(aPhysicalLink); |
|
2679 physicalLink->DeleteKeyRefresher(); |
|
2680 return EFalse; |
|
2681 } |
|
2682 |
|
2683 void CPhysicalLink::DeleteKeyRefresher() |
|
2684 { |
|
2685 LOG_FUNC |
|
2686 delete iKeyRefresher; |
|
2687 iKeyRefresher = NULL; |
|
2688 } |
|
2689 |
|
2690 TBool CPhysicalLink::IsEncryptionDisabledForRoleSwitch() const |
2690 TBool CPhysicalLink::IsEncryptionDisabledForRoleSwitch() const |
2691 /** |
2691 /** |
2692 If link is encrypted, but role switcher temporarily disabled encryption, returns true. |
2692 If link is encrypted, but role switcher temporarily disabled encryption, returns true. |
2693 **/ |
2693 **/ |
2694 { |
2694 { |
2732 //Arbitrate even if there isn't an outstanding local park mode request beacuse |
2732 //Arbitrate even if there isn't an outstanding local park mode request beacuse |
2733 //the remote device may be requesting park mode. |
2733 //the remote device may be requesting park mode. |
2734 return Arbitrate(); |
2734 return Arbitrate(); |
2735 } |
2735 } |
2736 |
2736 |
|
2737 TInt CPhysicalLink::OverrideLPMWithTimeout(TUint aTimeout) |
|
2738 { |
|
2739 LOG_FUNC |
|
2740 if(aTimeout == 0) |
|
2741 { |
|
2742 return KErrNone; //facility not wanted |
|
2743 } |
|
2744 |
|
2745 TInt rerr = OverrideLPM(); |
|
2746 QueueLPMOverrideTimer(aTimeout); |
|
2747 |
|
2748 return rerr; |
|
2749 } |
|
2750 |
2737 TInt CPhysicalLink::OverrideLPM() |
2751 TInt CPhysicalLink::OverrideLPM() |
2738 /** |
2752 /** |
2739 A request has come in that requires us to ensure we are not using |
2753 A request has come in that requires us to ensure we are not using |
2740 an LPM (low power mode). |
2754 an LPM (low power mode). |
2741 |
2755 |
2744 { |
2758 { |
2745 LOG_FUNC |
2759 LOG_FUNC |
2746 iOverrideLPMRequests = ETrue; |
2760 iOverrideLPMRequests = ETrue; |
2747 |
2761 |
2748 return Arbitrate(); |
2762 return Arbitrate(); |
|
2763 } |
|
2764 |
|
2765 /*static*/ TInt CPhysicalLink::OverrideLPMTimeoutCallback(TAny* aCPhysicalLink) |
|
2766 { |
|
2767 LOG_STATIC_FUNC |
|
2768 CPhysicalLink* c = reinterpret_cast<CPhysicalLink*>(aCPhysicalLink); |
|
2769 TInt err = c->UndoOverrideLPM(); |
|
2770 //we deliberately ignore this return value because we can't do anything to correct the error situation |
|
2771 if (KErrNone != err) |
|
2772 { |
|
2773 LOG2(_L("Physical link: UndoOverrideLPM returned an error %d on the connection 0x%08x"), err, c); |
|
2774 } |
|
2775 c->iLPMOverrideTimerQueued = EFalse; |
|
2776 return KErrNone; |
2749 } |
2777 } |
2750 |
2778 |
2751 TInt CPhysicalLink::UndoOverrideLPM() |
2779 TInt CPhysicalLink::UndoOverrideLPM() |
2752 /** |
2780 /** |
2753 A need to ensure we are not in LPM has gone. |
2781 A need to ensure we are not in LPM has gone. |
3086 iPinRequester = NULL; |
3114 iPinRequester = NULL; |
3087 iPinHandler = NULL; |
3115 iPinHandler = NULL; |
3088 AuthenticationComplete(EPinRequestPending); |
3116 AuthenticationComplete(EPinRequestPending); |
3089 } |
3117 } |
3090 |
3118 |
|
3119 |
3091 TInt CPhysicalLink::RequestHold() |
3120 TInt CPhysicalLink::RequestHold() |
3092 { |
3121 { |
3093 LOG_FUNC |
3122 LOG_FUNC |
3094 if (!IsConnected()) |
3123 return RequestMode(EHoldMode); |
3095 { |
3124 } |
3096 return KErrDisconnected; |
3125 |
3097 } |
3126 TInt CPhysicalLink::RequestSniff() |
3098 return iLowPowModeCtrl.ChangeMode(EHoldMode, iHandle); |
3127 { |
|
3128 LOG_FUNC |
|
3129 return RequestMode(ESniffMode); |
|
3130 } |
|
3131 |
|
3132 TInt CPhysicalLink::RequestPark() |
|
3133 { |
|
3134 LOG_FUNC |
|
3135 return RequestMode(EParkMode); |
|
3136 } |
|
3137 |
|
3138 TInt CPhysicalLink::RequestActive() |
|
3139 { |
|
3140 LOG_FUNC |
|
3141 return RequestMode(EActiveMode); |
3099 } |
3142 } |
3100 |
3143 |
3101 void CPhysicalLink::ReadNewPhysicalLinkMetricValue(TUint aIoctlName, CBTProxySAP& aSAP, TInt aCurrentValue) |
3144 void CPhysicalLink::ReadNewPhysicalLinkMetricValue(TUint aIoctlName, CBTProxySAP& aSAP, TInt aCurrentValue) |
3102 { |
3145 { |
3103 LOG_FUNC |
3146 LOG_FUNC |
3361 TInt CArbitrationDelayTimer::Start(TBool aImmediate, TBool aLocalPriority) |
3409 TInt CArbitrationDelayTimer::Start(TBool aImmediate, TBool aLocalPriority) |
3362 { |
3410 { |
3363 LOG_FUNC |
3411 LOG_FUNC |
3364 // Work out what the local priority will be now |
3412 // Work out what the local priority will be now |
3365 iLocalPriority = iLocalPriority || aLocalPriority; |
3413 iLocalPriority = iLocalPriority || aLocalPriority; |
3366 LOG1(_L8("Arbitration: Local Priority now %d"), iLocalPriority); |
3414 LOG1(_L8("Arbitraion: Local Priority now %d"), iLocalPriority); |
3367 if(aImmediate) |
3415 if(aImmediate) |
3368 { |
3416 { |
3369 LOG(_L8("Arbitration: Immediate Arbitration Requested...")); |
3417 LOG(_L8("Arbitraion: Immediate Arbitration Requested...")); |
3370 CancelButPreserveLocalPriority(); |
3418 CancelButPreserveLocalPriority(); |
3371 return DoArbitrate(); |
3419 return DoArbitrate(); |
3372 } |
3420 } |
3373 else if(!IsActive()) |
3421 else if(!IsActive()) |
3374 { |
3422 { |
3375 LOG(_L8("Arbitration: Arbitration requested, will execute after delay timer...")); |
3423 LOG(_L8("Arbitraion: Arbitration requested, will execute after delay timer...")); |
3376 After(KBTArbitrationDelay); |
3424 After(KBTArbitrationDelay); |
3377 } |
3425 } |
3378 else // timer is already on its way |
3426 else // timer is already on its way |
3379 { |
3427 { |
3380 LOG(_L8("Arbitration: Arbitration delay timer still pending...")); |
3428 LOG(_L8("Arbitraion: Arbitration delay timer still pending...")); |
3381 } |
3429 } |
3382 return KErrNone; |
3430 return KErrNone; |
3383 } |
3431 } |
3384 |
3432 |
3385 void CArbitrationDelayTimer::Restart() |
3433 void CArbitrationDelayTimer::Restart() |
3386 { |
3434 { |
3387 LOG_FUNC |
3435 LOG_FUNC |
3388 LOG(_L8("Arbitration: Arbitration timer restarted...")); |
3436 LOG(_L8("Arbitraion: Arbitration timer restarted...")); |
3389 CancelButPreserveLocalPriority(); |
3437 CancelButPreserveLocalPriority(); |
3390 After(KBTArbitrationDelay); |
3438 After(KBTArbitrationDelay); |
3391 } |
3439 } |
3392 |
3440 |
3393 void CArbitrationDelayTimer::CancelButPreserveLocalPriority() |
3441 void CArbitrationDelayTimer::CancelButPreserveLocalPriority() |
3941 LOG_FUNC |
3989 LOG_FUNC |
3942 TRAPD(err, DoChangeModeL(aMode, aHandle)); |
3990 TRAPD(err, DoChangeModeL(aMode, aHandle)); |
3943 return err; |
3991 return err; |
3944 } |
3992 } |
3945 |
3993 |
3946 TInt TLowPowModeCmdController::ExecuteModeChange(TBTLinkMode aTargetMode) |
|
3947 { |
|
3948 LOG_FUNC |
|
3949 iTargetMode = aTargetMode; |
|
3950 if(iTargetMode != iParent.LinkState().LinkMode()) |
|
3951 { |
|
3952 if(iParent.LinkState().LinkMode() != EActiveMode) |
|
3953 { |
|
3954 //the current mode is not in Active Mode, therefore the mode need to change to active first before change to other mode. |
|
3955 LOG(_L8("ExecuteModeChange: Exiting existing LPM mode...")); |
|
3956 return ExitMode(iParent.LinkState().LinkMode(), iParent.Handle()); |
|
3957 } |
|
3958 //the current mode is in Active mode, therefore the mode is ready to go other mode. |
|
3959 if(iTargetMode == EHoldMode) |
|
3960 { |
|
3961 LOG(_L8("ExecuteModeChange: Entering Hold mode...")); |
|
3962 return ChangeMode(EHoldMode, iParent.Handle()); |
|
3963 } |
|
3964 else if(iTargetMode == ESniffMode) |
|
3965 { |
|
3966 LOG(_L8("ExecuteModeChange: Entering Sniff mode...")); |
|
3967 return ChangeMode(ESniffMode, iParent.Handle()); |
|
3968 } |
|
3969 else if(iTargetMode == EParkMode) |
|
3970 { |
|
3971 LOG(_L8("ExecuteModeChange: Entering Park mode...")); |
|
3972 return ChangeMode(EParkMode, iParent.Handle()); |
|
3973 } |
|
3974 else if(iTargetMode == EActiveMode) |
|
3975 { |
|
3976 LOG(_L8("ExecuteModeChange: Staying in Active mode...")); |
|
3977 return KErrNone; |
|
3978 } |
|
3979 // Shouldn't reach here, we have a strange mode |
|
3980 DEBUG_PANIC_LINENUM; |
|
3981 } |
|
3982 LOG(_L8("ExecuteModeChange: Already in correct LPM, not doing anything")); |
|
3983 return KErrNone; |
|
3984 } |
|
3985 |
|
3986 void TLowPowModeCmdController::SniffL(THCIConnHandle aHandleToRemote) |
3994 void TLowPowModeCmdController::SniffL(THCIConnHandle aHandleToRemote) |
3987 { |
3995 { |
3988 LOG_FUNC |
3996 LOG_FUNC |
3989 CSniffModeCommand* cmd = CSniffModeCommand::NewL(aHandleToRemote, KBTSniffModeMaxInterval, KBTSniffModeMinInterval, KBTSniffModeAttempt, KBTSniffModeTimeout); |
3997 CSniffModeCommand* cmd = CSniffModeCommand::NewL(aHandleToRemote, KBTSniffModeMaxInterval, KBTSniffModeMinInterval, KBTSniffModeAttempt, KBTSniffModeTimeout); |
3990 |
3998 |
4050 iOutstandingCmd = EFalse; // reset the outstanding flag |
4058 iOutstandingCmd = EFalse; // reset the outstanding flag |
4051 |
4059 |
4052 LOG2(_L("TLowPowModeCmdController::MhcqcCommandEventReceived: event:%d opcode:0x%x"), code, aRelatedCommand->Opcode()); |
4060 LOG2(_L("TLowPowModeCmdController::MhcqcCommandEventReceived: event:%d opcode:0x%x"), code, aRelatedCommand->Opcode()); |
4053 |
4061 |
4054 const TModeChangeEvent& modeChangeEvent = TModeChangeEvent::Cast(aEvent); |
4062 const TModeChangeEvent& modeChangeEvent = TModeChangeEvent::Cast(aEvent); |
4055 TBTLinkMode currentmode = EActiveMode; |
4063 TBTLinkMode mode = EActiveMode; |
4056 switch(modeChangeEvent.CurrentMode()) |
4064 switch(modeChangeEvent.CurrentMode()) |
4057 { |
4065 { |
4058 // Mode 0, as defined for the Mode Change Event, is Active Mode |
4066 // Mode 0, as defined for the Mode Change Event, is Active Mode |
4059 case 0: |
4067 case 0: |
4060 break; |
4068 break; |
4061 case 1: |
4069 case 1: |
4062 currentmode = EHoldMode; |
4070 mode = EHoldMode; |
4063 break; |
4071 break; |
4064 case 2: |
4072 case 2: |
4065 currentmode = ESniffMode; |
4073 mode = ESniffMode; |
4066 break; |
4074 break; |
4067 case 3: |
4075 case 3: |
4068 currentmode = EParkMode; |
4076 mode = EParkMode; |
4069 break; |
4077 break; |
4070 default: |
4078 default: |
4071 __ASSERT_ALWAYS(EFalse, Panic(EHCICommandBadArgument)); |
4079 __ASSERT_ALWAYS(EFalse, Panic(EHCICommandBadArgument)); |
4072 break; |
4080 break; |
4073 } |
4081 } |
4074 // In the HCI_Facade, in this situation, CPhysicalLinksManager::ModeChanged() is called. |
4082 // In the HCI_Facade, in this situation, CPhysicalLinksManager::ModeChanged() is called. |
4075 // Since this methods find the CPhysicalLink object (that is iParent) and then call its |
4083 // Since this methods find the CPhysicalLink object (that is iParent) and then call its |
4076 // ModeChange method, we can call it directly. |
4084 // ModeChange method, we can call it directly. |
4077 iParent.ModeChange(aEvent.ErrorCode(), modeChangeEvent.ConnectionHandle(), currentmode, modeChangeEvent.Interval()); |
4085 iParent.ModeChange(aEvent.ErrorCode(), modeChangeEvent.ConnectionHandle(), mode, modeChangeEvent.Interval()); |
4078 //pass the current mode into Gear box. let gear box to decide if the mode is on the target mode. |
|
4079 //if it is, the gear box returns KErrNone, if it is not, the gear box will make another request for the target mode |
|
4080 if (aEvent.ErrorCode() == EOK) |
|
4081 { |
|
4082 TInt err = ExecuteModeChange(iTargetMode); |
|
4083 LOG1(_L("TLowPowModeCmdController::ExecuteModeChange: err:%d"), err); |
|
4084 } |
|
4085 } |
4086 } |
4086 } |
4087 } |
4087 |
4088 |
4088 void TLowPowModeCmdController::MhcqcCommandErrored(TInt __DEBUG_ONLY(aErrorCode), const CHCICommandBase* __DEBUG_ONLY(aCommand)) |
4089 void TLowPowModeCmdController::MhcqcCommandErrored(TInt __DEBUG_ONLY(aErrorCode), const CHCICommandBase* __DEBUG_ONLY(aCommand)) |
4089 { |
4090 { |