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 "PhysicalLinkHelper.h" |
28 #include "roleswitchhelper.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" |
32 |
33 |
33 #include <bt_sock.h> |
34 #include <bt_sock.h> |
34 |
35 |
35 #include <bluetooth/hci/commandstatusevent.h> |
36 #include <bluetooth/hci/commandstatusevent.h> |
36 #include <bluetooth/hci/sniffmodecommand.h> |
37 #include <bluetooth/hci/sniffmodecommand.h> |
89 , iDeviceResult(KDeviceNotObtained) |
90 , iDeviceResult(KDeviceNotObtained) |
90 , iRegistryHelpers(_FOFF(CBTRegistryHelperBase,iLink)) |
91 , iRegistryHelpers(_FOFF(CBTRegistryHelperBase,iLink)) |
91 , iProxySAPs(_FOFF(CBTProxySAP, iQueueLink)) |
92 , iProxySAPs(_FOFF(CBTProxySAP, iQueueLink)) |
92 , iOverrideParkRequests(EFalse) |
93 , iOverrideParkRequests(EFalse) |
93 , iOverrideLPMRequests(EFalse) |
94 , 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 } |
|
127 |
122 |
128 LOG(_L("sec\tClosing subscribers...")) |
123 LOG(_L("sec\tClosing subscribers...")) |
129 |
124 |
130 LOG(_L("sec\tClosing helpers...")) |
125 LOG(_L("sec\tClosing helpers...")) |
131 TSglQueIter<CBTRegistryHelperBase> iter(iRegistryHelpers); |
126 TSglQueIter<CBTRegistryHelperBase> iter(iRegistryHelpers); |
147 delete iNumericComparator; |
142 delete iNumericComparator; |
148 delete iUserConfirmer; |
143 delete iUserConfirmer; |
149 delete iPasskeyEntry; |
144 delete iPasskeyEntry; |
150 delete iArbitrationDelay; |
145 delete iArbitrationDelay; |
151 delete iRoleSwitchCompleteCallBack; |
146 delete iRoleSwitchCompleteCallBack; |
|
147 delete iKeyRefreshCompleteCallBack; |
152 delete iEncryptionEnforcer; |
148 delete iEncryptionEnforcer; |
153 |
149 |
154 DeleteRoleSwitcher(); |
150 DeleteRoleSwitcher(); |
|
151 DeleteKeyRefresher(); |
155 } |
152 } |
156 |
153 |
157 void CPhysicalLink::ConstructL() |
154 void CPhysicalLink::ConstructL() |
158 { |
155 { |
159 LOG_FUNC |
156 LOG_FUNC |
162 iArbitrationDelay = CArbitrationDelayTimer::NewL(this); |
159 iArbitrationDelay = CArbitrationDelayTimer::NewL(this); |
163 |
160 |
164 TCallBack cb1(RoleSwitchCompleteCallBack, this); |
161 TCallBack cb1(RoleSwitchCompleteCallBack, this); |
165 iRoleSwitchCompleteCallBack = new (ELeave)CAsyncCallBack(cb1, EActiveHighPriority); |
162 iRoleSwitchCompleteCallBack = new (ELeave)CAsyncCallBack(cb1, EActiveHighPriority); |
166 |
163 |
167 TCallBack cb2(OverrideLPMTimeoutCallback, this); |
164 TCallBack cb2(KeyRefreshCompleteCallBack, this); |
168 iOverrideLPMTimerEntry.Set(cb2); |
165 iKeyRefreshCompleteCallBack = new (ELeave)CAsyncCallBack(cb2, EActiveHighPriority); |
169 |
166 |
170 iPhysicalLinkMetrics = CPhysicalLinkMetrics::NewL(*this, iLinksMan.HCIFacade().CommandQController()); |
167 iPhysicalLinkMetrics = CPhysicalLinkMetrics::NewL(*this, iLinksMan.HCIFacade().CommandQController()); |
171 } |
168 } |
172 |
169 |
173 TBool CPhysicalLink::HasHandle(THCIConnHandle aHandle) const |
170 TBool CPhysicalLink::HasHandle(THCIConnHandle aHandle) const |
174 { |
171 { |
235 err = KErrNotSupported; |
232 err = KErrNotSupported; |
236 *reinterpret_cast<MBluetoothControlPlaneToken**>(aOutToken) = NULL; |
233 *reinterpret_cast<MBluetoothControlPlaneToken**>(aOutToken) = NULL; |
237 } |
234 } |
238 else |
235 else |
239 { |
236 { |
240 if (iAutoKeyRefreshQue.IsEmpty()) |
237 // Only refresh the key if no-one is preventing it and we aren't still |
241 { |
238 // refreshing the key from a previous request. Note that although |
242 TRAP_IGNORE(iLinksMan.HCIFacade().RefreshEncryptionKeyL(iHandle)); |
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 } |
243 // If we can't refresh the encryption key, there's not much we can do |
250 // If we can't refresh the encryption key, there's not much we can do |
244 } |
251 } |
245 XAutoKeyRefreshToken* token = new XAutoKeyRefreshToken(); |
252 XAutoKeyRefreshToken* token = new XAutoKeyRefreshToken(); |
246 if (token) |
253 if (token) |
247 { |
254 { |
1360 { |
1367 { |
1361 LOG_FUNC |
1368 LOG_FUNC |
1362 CBTDeviceNameChanger* nameChanger = CBTDeviceNameChanger::NewL(iRegSess, *this); |
1369 CBTDeviceNameChanger* nameChanger = CBTDeviceNameChanger::NewL(iRegSess, *this); |
1363 iRegistryHelpers.AddLast(*nameChanger); |
1370 iRegistryHelpers.AddLast(*nameChanger); |
1364 nameChanger->Start(BDAddr(), aName); |
1371 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 } |
1365 } |
1383 } |
1366 |
1384 |
1367 void CPhysicalLink::Disconnection(THCIErrorCode aErr, THCIConnHandle aConnH, THCIErrorCode aResult) |
1385 void CPhysicalLink::Disconnection(THCIErrorCode aErr, THCIConnHandle aConnH, THCIErrorCode aResult) |
1368 { |
1386 { |
1369 LOG_FUNC |
1387 LOG_FUNC |
2225 } |
2243 } |
2226 BTSocketTimer::Remove(iIdleTimerEntry); |
2244 BTSocketTimer::Remove(iIdleTimerEntry); |
2227 iIdleTimerQueued = EFalse; |
2245 iIdleTimerQueued = EFalse; |
2228 } |
2246 } |
2229 |
2247 |
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 |
|
2246 void CPhysicalLink::NotifyStateChange(TBTBasebandEventNotification& aEvent) |
2248 void CPhysicalLink::NotifyStateChange(TBTBasebandEventNotification& aEvent) |
2247 { |
2249 { |
2248 LOG_FUNC |
2250 LOG_FUNC |
2249 // If this event is 'physical link down' / 'physical link error' then any ProxySAP |
2251 // If this event is 'physical link down' / 'physical link error' then any ProxySAP |
2250 // subscribers will unsubscribe as a result of PhysicalLinkChange being called. |
2252 // subscribers will unsubscribe as a result of PhysicalLinkChange being called. |
2662 LOG_FUNC |
2664 LOG_FUNC |
2663 delete iRoleSwitcher; |
2665 delete iRoleSwitcher; |
2664 iRoleSwitcher = NULL; |
2666 iRoleSwitcher = NULL; |
2665 } |
2667 } |
2666 |
2668 |
|
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 |
2667 TBool CPhysicalLink::IsEncryptionDisabledForRoleSwitch() const |
2690 TBool CPhysicalLink::IsEncryptionDisabledForRoleSwitch() const |
2668 /** |
2691 /** |
2669 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. |
2670 **/ |
2693 **/ |
2671 { |
2694 { |
2709 //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 |
2710 //the remote device may be requesting park mode. |
2733 //the remote device may be requesting park mode. |
2711 return Arbitrate(); |
2734 return Arbitrate(); |
2712 } |
2735 } |
2713 |
2736 |
2714 TInt CPhysicalLink::OverrideLPMWithTimeout(TUint aTimeout) |
|
2715 { |
|
2716 LOG_FUNC |
|
2717 if(aTimeout == 0) |
|
2718 { |
|
2719 return KErrNone; //facility not wanted |
|
2720 } |
|
2721 |
|
2722 TInt rerr = OverrideLPM(); |
|
2723 QueueLPMOverrideTimer(aTimeout); |
|
2724 |
|
2725 return rerr; |
|
2726 } |
|
2727 |
|
2728 TInt CPhysicalLink::OverrideLPM() |
2737 TInt CPhysicalLink::OverrideLPM() |
2729 /** |
2738 /** |
2730 A request has come in that requires us to ensure we are not using |
2739 A request has come in that requires us to ensure we are not using |
2731 an LPM (low power mode). |
2740 an LPM (low power mode). |
2732 |
2741 |
2735 { |
2744 { |
2736 LOG_FUNC |
2745 LOG_FUNC |
2737 iOverrideLPMRequests = ETrue; |
2746 iOverrideLPMRequests = ETrue; |
2738 |
2747 |
2739 return Arbitrate(); |
2748 return Arbitrate(); |
2740 } |
|
2741 |
|
2742 /*static*/ TInt CPhysicalLink::OverrideLPMTimeoutCallback(TAny* aCPhysicalLink) |
|
2743 { |
|
2744 LOG_STATIC_FUNC |
|
2745 CPhysicalLink* c = reinterpret_cast<CPhysicalLink*>(aCPhysicalLink); |
|
2746 TInt err = c->UndoOverrideLPM(); |
|
2747 //we deliberately ignore this return value because we can't do anything to correct the error situation |
|
2748 if (KErrNone != err) |
|
2749 { |
|
2750 LOG2(_L("Physical link: UndoOverrideLPM returned an error %d on the connection 0x%08x"), err, c); |
|
2751 } |
|
2752 c->iLPMOverrideTimerQueued = EFalse; |
|
2753 return KErrNone; |
|
2754 } |
2749 } |
2755 |
2750 |
2756 TInt CPhysicalLink::UndoOverrideLPM() |
2751 TInt CPhysicalLink::UndoOverrideLPM() |
2757 /** |
2752 /** |
2758 A need to ensure we are not in LPM has gone. |
2753 A need to ensure we are not in LPM has gone. |