|
1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Implementation of proxy SAP. |
|
15 // |
|
16 // |
|
17 |
|
18 #include <bluetooth/logger.h> |
|
19 #include "ProxySAP.h" |
|
20 #include "linkutil.h" |
|
21 #include "linkconsts.h" |
|
22 #include "RawConduit.h" |
|
23 #include "physicallinksmanager.h" |
|
24 #include "Basebandmodel.h" |
|
25 #include "BTSec.h" |
|
26 #include "linkmgr.h" |
|
27 |
|
28 #include <bluetooth/hci/aclpacketconsts.h> |
|
29 |
|
30 #ifdef __FLOG_ACTIVE |
|
31 _LIT8(KLogComponent, LOG_COMPONENT_LINKMGR); |
|
32 #endif |
|
33 |
|
34 #ifdef _DEBUG |
|
35 PANICCATEGORY("proxysap"); |
|
36 #endif |
|
37 |
|
38 //Diagnostic string for security check failures, in builds without platsec |
|
39 //diagnostics this will be NULL. |
|
40 const char* const KBT_PROXYSAP_NAME_DIAG = __PLATSEC_DIAGNOSTIC_STRING("Bluetooth Proxy SAP"); |
|
41 |
|
42 CBTProxySAP::CBTProxySAP(CPhysicalLinksManager& aLinksMan, CPhysicalLink* aPhysicalLink) |
|
43 : CBTBasebandSAP(aLinksMan, aPhysicalLink), |
|
44 iRequestedLinkPolicy(EHoldMode | ESniffMode | EParkMode, ETrue), |
|
45 iNotifiedUp(EFalse), iTerminating(ENone), iBasebandNotifyOptions(0), |
|
46 iEventNotificationQueue(_FOFF(TBTQueuedBasebandEventNotification, iLink)), |
|
47 iEventNotificationStatus(EDisabled) |
|
48 { |
|
49 LOG1(_L("Creating proxy SAP 0x%08x"), this); |
|
50 #ifdef PROXY_COMMUNICATES |
|
51 iHandle = KHCIBroadcastHandle; |
|
52 #endif |
|
53 } |
|
54 |
|
55 CBTProxySAP* CBTProxySAP::NewLC(CPhysicalLinksManager& aConnectionMan, CPhysicalLink* aPhysicalSAP) |
|
56 { |
|
57 CBTProxySAP* s = new(ELeave) CBTProxySAP(aConnectionMan, aPhysicalSAP); |
|
58 CleanupStack::PushL(s); |
|
59 s->ConstructL(); |
|
60 return s; |
|
61 } |
|
62 |
|
63 CBTProxySAP* CBTProxySAP::NewL(CPhysicalLinksManager& aConnectionMan, CPhysicalLink* aPhysicalSAP) |
|
64 { |
|
65 CBTProxySAP* s = CBTProxySAP::NewLC(aConnectionMan, aPhysicalSAP); |
|
66 CleanupStack::Pop(s); |
|
67 return s; |
|
68 } |
|
69 |
|
70 void CBTProxySAP::ConstructL() |
|
71 { |
|
72 CBTBasebandSAP::ConstructL(); |
|
73 iAsyncCallback = new(ELeave) CAsyncCallBack(CActive::EPriorityStandard); |
|
74 |
|
75 if(iPhysicalLink) |
|
76 { |
|
77 User::LeaveIfError(iPhysicalLink->SubscribeProxySAP(*this)); |
|
78 } |
|
79 // now we need to go async and check whether the physical link is up |
|
80 // has to be async because we don't have a socket at the moment |
|
81 AsyncCheckLinkUp(); |
|
82 } |
|
83 |
|
84 void CBTProxySAP::ClearPhysicalLink() |
|
85 { |
|
86 if (iPhysicalLink) |
|
87 { |
|
88 iPhysicalLink->UnsubscribeProxySAP(*this); |
|
89 iPhysicalLink = NULL; |
|
90 } |
|
91 } |
|
92 |
|
93 CBTProxySAP::~CBTProxySAP() |
|
94 { |
|
95 LOG1(_L("Deleting proxy SAP 0x%08x"), this); |
|
96 |
|
97 // If iTerminating is set we are waiting for iLinksMan to call us back |
|
98 // which means that it holds a pointer to this ProxySAP |
|
99 if (iTerminating!=ENone) |
|
100 { |
|
101 __ASSERT_DEBUG(EFalse, Panic(EBTProxySAPBadCanClose)); |
|
102 iLinksMan.ClearTerminatingProxy(this); |
|
103 } |
|
104 |
|
105 ClearPhysicalLink(); |
|
106 /*Remove this proxy SAP from the PLM queue*/ |
|
107 iPLMLink.Deque(); |
|
108 delete iAsyncCallback; |
|
109 delete iRawConduit; |
|
110 } |
|
111 |
|
112 // from SAP - the proxy will not do all of these |
|
113 void CBTProxySAP::Start() |
|
114 { |
|
115 // do nothing |
|
116 } |
|
117 |
|
118 void CBTProxySAP::RemName(TSockAddr& aAddr) const |
|
119 { |
|
120 // our name is the same is that of the PHY, assuming it is connected |
|
121 // note esock doesn't allow a great deal of maneouvour on errors here! |
|
122 if(iPhysicalLink && iPhysicalLink->IsConnected()) |
|
123 { |
|
124 TBTSockAddr bbAddr(aAddr); |
|
125 bbAddr.SetBTAddr(iPhysicalLink->BDAddr()); |
|
126 aAddr=bbAddr; // Convert back |
|
127 } |
|
128 } |
|
129 |
|
130 TInt CBTProxySAP::SetRemName(TSockAddr& aAddr) |
|
131 { |
|
132 TBTSockAddr addr = TBTSockAddr::Cast(aAddr); |
|
133 iRemoteDev = addr.BTAddr(); |
|
134 |
|
135 // we now know our remote address so should try to get a PHY if there |
|
136 CPhysicalLink *link = iLinksMan.FindPhysicalLink(iRemoteDev); |
|
137 |
|
138 // If we're (re-)using the same physical link, there's no |
|
139 // reason to subscribe again |
|
140 if (link != iPhysicalLink) |
|
141 { |
|
142 // Unsubscribe from old link |
|
143 if (iPhysicalLink) |
|
144 { |
|
145 iPhysicalLink->UnsubscribeProxySAP(*this); |
|
146 } |
|
147 |
|
148 iPhysicalLink = link; |
|
149 |
|
150 // Subscribe to new one |
|
151 if (iPhysicalLink) |
|
152 { |
|
153 return iPhysicalLink->SubscribeProxySAP(*this); |
|
154 } |
|
155 } |
|
156 |
|
157 // in any case return no error since the BAP may try to create PHY |
|
158 return KErrNone; |
|
159 } |
|
160 |
|
161 TInt CBTProxySAP::GetOption(TUint aLevel,TUint aName,TDes8& aOption) const |
|
162 { |
|
163 TInt rerr = KErrNone; |
|
164 |
|
165 if(aLevel != KSolBtLMProxy) |
|
166 { |
|
167 rerr = KErrNotSupported; |
|
168 } |
|
169 |
|
170 switch (aName) |
|
171 { |
|
172 case EBBEnumeratePhysicalLinks: |
|
173 iLinksMan.EnumeratePhysicalLinks(aOption); |
|
174 break; |
|
175 case EBBGetPhysicalLinkState: |
|
176 { |
|
177 if (aOption.Length() != sizeof(TBTBasebandEventNotification)) |
|
178 return KErrArgument; |
|
179 |
|
180 if (!iPhysicalLink) |
|
181 { |
|
182 LOG1(_L("GetOption called on non-existent Phy ....so return %d (KErrDisconnected)"), KErrDisconnected); |
|
183 return KErrDisconnected; |
|
184 } |
|
185 TBTBasebandEventNotification basebandState; |
|
186 iPhysicalLink->GetCurrentBasebandState(basebandState); |
|
187 TBTBasebandEvent pkcgEvent(basebandState); |
|
188 aOption = pkcgEvent; |
|
189 } |
|
190 break; |
|
191 default: |
|
192 rerr = KErrArgument; |
|
193 break; |
|
194 } |
|
195 return rerr; |
|
196 } |
|
197 |
|
198 void CBTProxySAP::Ioctl(TUint aLevel,TUint aName,TDes8* aOption) |
|
199 { |
|
200 if (aLevel == KSolBtLMProxy) |
|
201 { |
|
202 switch(aName) |
|
203 { |
|
204 case KLMReadRssiIoctl: |
|
205 case KLMReadLinkQualityIoctl: |
|
206 case KLMReadFailedContactCounterIoctl: |
|
207 case KLMReadCurrentTransmitPowerLevelIoctl: |
|
208 { |
|
209 if (!aOption || aOption->Length() != sizeof(TInt)) |
|
210 { |
|
211 IoctlComplete(KErrArgument, aLevel, aName); |
|
212 break; |
|
213 } |
|
214 // Add the current request to a queue; pass this pointer to call IoctlComplete() |
|
215 // when result is available from the controller. Multiple SAPs can queue data on |
|
216 // the same physical link. |
|
217 TPckgBuf<TInt> currentValuePckg; |
|
218 currentValuePckg.Copy(*aOption); |
|
219 |
|
220 if(iPhysicalLink) |
|
221 { |
|
222 iPhysicalLink->ReadNewPhysicalLinkMetricValue(aName, *this, currentValuePckg()); |
|
223 } |
|
224 else |
|
225 { |
|
226 IoctlComplete(KErrDisconnected, KSolBtLMProxy, aName, NULL); |
|
227 } |
|
228 |
|
229 break; |
|
230 } |
|
231 case KLMBasebandEventOneShotNotificationIoctl: |
|
232 { |
|
233 ASSERT_DEBUG(iEventNotificationStatus == EDisabled); |
|
234 iEventNotificationStatus = EEnabledOneShot; |
|
235 const TBTBasebandEventNotification* option = reinterpret_cast<const TBTBasebandEventNotification*>(aOption->Ptr()); |
|
236 __ASSERT_DEBUG(option->EventType(), Panic(EBTProxySAPInvalidEventMask)); |
|
237 SetBasebandNotificationOptions(option->EventType()); |
|
238 } |
|
239 break; |
|
240 |
|
241 case KLMBasebandEventNotificationIoctl: |
|
242 { |
|
243 ASSERT_DEBUG(iEventNotificationStatus != EEnabledOneShot); |
|
244 const TBTBasebandEventNotification* option = reinterpret_cast<const TBTBasebandEventNotification*>(aOption->Ptr()); |
|
245 SetBasebandNotificationOptions(option->EventType()); |
|
246 |
|
247 if(iEventNotificationStatus == EDisabled) |
|
248 { |
|
249 // Send an initial event describing the current state of the |
|
250 // baseband link. |
|
251 TBTBasebandEventNotification basebandState; |
|
252 |
|
253 if (!iPhysicalLink) |
|
254 { |
|
255 LOG1(_L("Ioctl called on non-existent Phy ....so indicate %d (KErrDisconnected)"), KErrDisconnected); |
|
256 SetNullBasebandState(basebandState); |
|
257 TBTBasebandEvent pkcgEvent(basebandState); |
|
258 IoctlComplete(KErrNone, KSolBtLMProxy, KLMBasebandEventNotificationIoctl, &pkcgEvent); |
|
259 } |
|
260 else |
|
261 { |
|
262 iPhysicalLink->GetCurrentBasebandState(basebandState); |
|
263 TBTBasebandEvent pkcgEvent(basebandState); |
|
264 IoctlComplete(KErrNone, KSolBtLMProxy, KLMBasebandEventNotificationIoctl, &pkcgEvent); |
|
265 } |
|
266 iEventNotificationStatus = EEnabledQueuing; |
|
267 } |
|
268 else |
|
269 { |
|
270 // Check if anything is currently in the queue. |
|
271 iEventNotificationStatus = EEnabledCanSend; |
|
272 |
|
273 if(!iEventNotificationQueue.IsEmpty()) |
|
274 { |
|
275 TBTQueuedBasebandEventNotification* e = iEventNotificationQueue.First(); |
|
276 iEventNotificationQueue.Remove(*e); |
|
277 TBTBasebandEventNotification event(e->EventType() & iBasebandNotifyOptions, e->ErrorCode()); |
|
278 delete e; |
|
279 |
|
280 if(event.EventType()) |
|
281 { |
|
282 TBTBasebandEvent pkcgEvent(event); |
|
283 IoctlComplete(KErrNone, KSolBtLMProxy, KLMBasebandEventNotificationIoctl, &pkcgEvent); |
|
284 iEventNotificationStatus = EEnabledQueuing; |
|
285 } |
|
286 } |
|
287 } |
|
288 } |
|
289 break; |
|
290 |
|
291 default: |
|
292 { |
|
293 IoctlComplete(KErrNotSupported, aLevel, aName); |
|
294 break; |
|
295 } |
|
296 }; |
|
297 } |
|
298 else |
|
299 { |
|
300 IoctlComplete(KErrNotSupported, aLevel, aName); |
|
301 } |
|
302 } |
|
303 |
|
304 void CBTProxySAP::IoctlComplete(TInt aErr, TUint /*aLevel*/, TUint /*aName*/, TDesC8* aBuf) |
|
305 { |
|
306 |
|
307 if (iSocket) |
|
308 { |
|
309 if (aErr==KErrNone) |
|
310 { |
|
311 iSocket->IoctlComplete(aBuf); |
|
312 } |
|
313 else |
|
314 { |
|
315 iSocket->Error(aErr, MSocketNotify::EErrorIoctl); |
|
316 } |
|
317 } |
|
318 } |
|
319 |
|
320 void CBTProxySAP::SetNullBasebandState(TBTBasebandEventNotification & aEvent) |
|
321 { |
|
322 // Populate the event with no physical link baseband state. |
|
323 TUint32 events = 0; |
|
324 |
|
325 events |= ENotifyPhysicalLinkDown; |
|
326 |
|
327 aEvent.SetEventType(events); |
|
328 aEvent.SetErrorCode(0); |
|
329 } |
|
330 |
|
331 void CBTProxySAP::CancelIoctl(TUint aLevel,TUint aName) |
|
332 { |
|
333 |
|
334 __ASSERT_DEBUG((aLevel == KSolBtLMProxy), Panic(EBTProxySAPInvalidIoctl)); |
|
335 |
|
336 if (aLevel == KSolBtLMProxy) |
|
337 { |
|
338 switch(aName) |
|
339 { |
|
340 case KLMBasebandEventNotificationIoctl: |
|
341 SetBasebandNotificationOptions(0); |
|
342 iEventNotificationStatus = EDisabled; |
|
343 ClearBasebandEventQueue(); |
|
344 break; |
|
345 |
|
346 case KLMBasebandEventOneShotNotificationIoctl: |
|
347 SetBasebandNotificationOptions(0); |
|
348 iEventNotificationStatus = EDisabled; |
|
349 ClearBasebandEventQueue(); |
|
350 break; |
|
351 case KLMReadRssiIoctl: |
|
352 case KLMReadLinkQualityIoctl: |
|
353 case KLMReadFailedContactCounterIoctl: |
|
354 case KLMReadCurrentTransmitPowerLevelIoctl: |
|
355 iPLMLink.Deque(); |
|
356 break; |
|
357 default: |
|
358 __ASSERT_DEBUG(EFalse, Panic(EBTProxySAPInvalidIoctl)); |
|
359 break; |
|
360 }; |
|
361 } |
|
362 } |
|
363 |
|
364 void CBTProxySAP::ClearBasebandEventQueue() |
|
365 { |
|
366 TSglQueIter<TBTQueuedBasebandEventNotification> iter(iEventNotificationQueue); |
|
367 while (iter) |
|
368 { |
|
369 TBTQueuedBasebandEventNotification* e = iter++; |
|
370 iEventNotificationQueue.Remove(*e); |
|
371 delete e; |
|
372 } |
|
373 } |
|
374 |
|
375 void CBTProxySAP::SetBasebandNotificationOptions(TUint32 aOption) |
|
376 { |
|
377 iBasebandNotifyOptions = aOption; |
|
378 } |
|
379 |
|
380 |
|
381 TInt CBTProxySAP::SAPSetOption(TUint aLevel,TUint aName, const TDesC8 &aOption) |
|
382 { |
|
383 LOG3(_L("SetOpt %d, %d on proxy SAP 0x%08x"), aLevel, aName, this); |
|
384 TInt rerr = KErrNone; |
|
385 |
|
386 // Arbitration will be required after most operations. |
|
387 TBool arbitrate = ETrue; |
|
388 TBool immediateArbitration = EFalse; |
|
389 TBool localPriority = EFalse; |
|
390 |
|
391 if(aLevel != KSolBtLMProxy) |
|
392 { |
|
393 rerr = KErrNotSupported; |
|
394 } |
|
395 |
|
396 if(!iPhysicalLink && |
|
397 aName!=EBBSubscribePhysicalLink) |
|
398 { |
|
399 rerr = KErrDisconnected; |
|
400 } |
|
401 |
|
402 if(rerr == KErrNone) |
|
403 { |
|
404 switch (aName) |
|
405 { |
|
406 case EBBSubscribePhysicalLink: |
|
407 { |
|
408 // Make sure we're not already subscribed |
|
409 if (iPhysicalLink) |
|
410 { |
|
411 __ASSERT_DEBUG(EFalse,Panic(EBTProxySAPAlreadySubscribed)); |
|
412 rerr = KErrArgument; |
|
413 break; |
|
414 } |
|
415 |
|
416 TPckgBuf<TBTDevAddr> pckg; |
|
417 pckg.Copy(aOption); |
|
418 // try to find a PHY from addr, and if successful subscribe to it |
|
419 iPhysicalLink = iLinksMan.FindPhysicalLink(pckg()); |
|
420 if (iPhysicalLink) |
|
421 { |
|
422 rerr = iPhysicalLink->SubscribeProxySAP(*this); |
|
423 if(rerr == KErrNone) |
|
424 { |
|
425 iRemoteDev = pckg(); |
|
426 } |
|
427 } |
|
428 else |
|
429 { |
|
430 LOG1(_L("Proxy SAP 0x%08x -- couldn't find physical link"), this); |
|
431 LOG(_L("Looking for addr: ")); |
|
432 LOGBTDEVADDR(pckg()); |
|
433 iLinksMan.DumpPhysicalLinks(); |
|
434 rerr = KErrDisconnected; |
|
435 } |
|
436 |
|
437 arbitrate = EFalse; |
|
438 } |
|
439 break; |
|
440 case EBBBeginRaw: |
|
441 //EBBBeginRaw requires additional security checking, NetworkControl |
|
442 //in addition to the LocalServices that was required to create the SAP |
|
443 |
|
444 __ASSERT_DEBUG(iSecurityChecker, User::Panic(KSECURITY_PANIC, EBTPanicNullSecurityChecker)); |
|
445 |
|
446 rerr = iSecurityChecker->CheckPolicy(KNETWORK_CONTROL, KBT_PROXYSAP_NAME_DIAG); |
|
447 if (rerr != KErrNone) |
|
448 { |
|
449 break; |
|
450 } |
|
451 if(!(iPhysicalLink && iPhysicalLink->Handle()!=KHCIBroadcastHandle)) |
|
452 //if no existing, connected PHY, try to find a random PHY which is |
|
453 { |
|
454 // We don't support this option if we're subscribed to the broadcast handle |
|
455 if (iPhysicalLink) |
|
456 { |
|
457 __ASSERT_DEBUG(EFalse,Panic(EBTProxySAPSubscribedToBroadcastHandle)); |
|
458 rerr = KErrArgument; |
|
459 break; |
|
460 } |
|
461 |
|
462 iPhysicalLink = iLinksMan.FindPhysicalLink(); |
|
463 if (iPhysicalLink) |
|
464 { |
|
465 rerr = iPhysicalLink->SubscribeProxySAP(*this); |
|
466 if(rerr == KErrNone) |
|
467 { |
|
468 iRemoteDev = iPhysicalLink->BDAddr(); |
|
469 } |
|
470 } |
|
471 else |
|
472 { |
|
473 rerr = KErrDisconnected; |
|
474 } |
|
475 } |
|
476 if(rerr == KErrNone) |
|
477 { |
|
478 rerr = CreateRawConduit(); |
|
479 } |
|
480 arbitrate = EFalse; |
|
481 break; |
|
482 case EBBCancelModeRequest: |
|
483 rerr = SetModeRequested(EActiveMode); |
|
484 break; |
|
485 case EBBRequestSniff: |
|
486 rerr = SetModeRequested(ESniffMode); |
|
487 localPriority = ETrue; |
|
488 break; |
|
489 // clients cannot ask for Hold |
|
490 case EBBRequestPark: |
|
491 rerr = SetModeRequested(EParkMode); |
|
492 localPriority = ETrue; |
|
493 break; |
|
494 case EBBRequestRoleMaster: |
|
495 if(iRequestedLinkPolicy.IsSwitchAllowed() && iPhysicalLink->IsRoleSwitchSupported()) |
|
496 { |
|
497 rerr = iPhysicalLink->RequestChangeRole(EMaster); |
|
498 arbitrate = EFalse; |
|
499 } |
|
500 else |
|
501 { |
|
502 rerr = KErrNotSupported; |
|
503 } |
|
504 break; |
|
505 |
|
506 case EBBRequestRoleSlave: |
|
507 if(iLinksMan.LinkManagerProtocol().IsRoleSwitchSupportedLocally() && |
|
508 iRequestedLinkPolicy.IsSwitchAllowed() && iPhysicalLink->IsRoleSwitchSupported()) |
|
509 { |
|
510 rerr = iPhysicalLink->RequestChangeRole(ESlave); |
|
511 arbitrate = EFalse; |
|
512 } |
|
513 else |
|
514 { |
|
515 rerr = KErrNotSupported; |
|
516 } |
|
517 break; |
|
518 |
|
519 case EBBRequestPreventRoleChange: |
|
520 iRequestedLinkPolicy.SetSwitchAllowed(EFalse); |
|
521 break; |
|
522 |
|
523 case EBBRequestAllowRoleChange: |
|
524 iRequestedLinkPolicy.SetSwitchAllowed(ETrue); |
|
525 break; |
|
526 |
|
527 case EBBRequestChangeSupportedPacketTypes: |
|
528 { |
|
529 TUint16 options = *reinterpret_cast<const TUint16*>(aOption.Ptr()); |
|
530 if(aOption.Length() != sizeof(TUint16)) |
|
531 { |
|
532 rerr = KErrArgument; |
|
533 } |
|
534 else |
|
535 { |
|
536 iPhysicalLink->ChangeConnectionPacketType(options); |
|
537 arbitrate = EFalse; |
|
538 } |
|
539 } |
|
540 break; |
|
541 |
|
542 case EBBRequestLinkAuthentication: |
|
543 rerr = iPhysicalLink->Authenticate(EFalse); |
|
544 break; |
|
545 |
|
546 case EBBRequestExplicitActiveMode: |
|
547 { |
|
548 TBool option = *reinterpret_cast<const TBool*>(aOption.Ptr()); |
|
549 if(aOption.Length() != sizeof(TBool)) |
|
550 { |
|
551 rerr = KErrArgument; |
|
552 } |
|
553 else |
|
554 { |
|
555 iRequestedActiveMode = option ? ETrue : EFalse; |
|
556 if(iRequestedActiveMode) |
|
557 { |
|
558 localPriority = ETrue; |
|
559 } |
|
560 } |
|
561 } |
|
562 break; |
|
563 |
|
564 default: |
|
565 { |
|
566 arbitrate = EFalse; |
|
567 if(aName & EBBRequestPreventAllLowPowerModes) |
|
568 { |
|
569 if (aName & EBBRequestPreventSniff) |
|
570 { |
|
571 if(iRequestedLinkPolicy.IsModeAllowed(ESniffMode)) |
|
572 { |
|
573 iRequestedLinkPolicy.SetModeAllowed(ESniffMode, EFalse); |
|
574 arbitrate = ETrue; |
|
575 } |
|
576 } |
|
577 if (aName & EBBRequestPreventHold) |
|
578 { |
|
579 if(iRequestedLinkPolicy.IsModeAllowed(EHoldMode)) |
|
580 { |
|
581 iRequestedLinkPolicy.SetModeAllowed(EHoldMode, EFalse); |
|
582 arbitrate = ETrue; |
|
583 } |
|
584 } |
|
585 if (aName & EBBRequestPreventPark) |
|
586 { |
|
587 if(iRequestedLinkPolicy.IsModeAllowed(EParkMode)) |
|
588 { |
|
589 iRequestedLinkPolicy.SetModeAllowed(EParkMode, EFalse); |
|
590 arbitrate = ETrue; |
|
591 } |
|
592 } |
|
593 |
|
594 immediateArbitration = ETrue; |
|
595 } |
|
596 else if (aName & EBBRequestAllowAllLowPowerModes) |
|
597 { |
|
598 if (aName & EBBRequestAllowSniff) |
|
599 { |
|
600 if(!(iRequestedLinkPolicy.IsModeAllowed(ESniffMode))) |
|
601 { |
|
602 iRequestedLinkPolicy.SetModeAllowed(ESniffMode, ETrue); |
|
603 arbitrate = ETrue; |
|
604 } |
|
605 } |
|
606 if (aName & EBBRequestAllowHold) |
|
607 { |
|
608 if(!(iRequestedLinkPolicy.IsModeAllowed(EHoldMode))) |
|
609 { |
|
610 iRequestedLinkPolicy.SetModeAllowed(EHoldMode, ETrue); |
|
611 arbitrate = ETrue; |
|
612 } |
|
613 } |
|
614 if (aName & EBBRequestAllowPark) |
|
615 { |
|
616 if(!(iRequestedLinkPolicy.IsModeAllowed(EParkMode))) |
|
617 { |
|
618 iRequestedLinkPolicy.SetModeAllowed(EParkMode, ETrue); |
|
619 arbitrate = ETrue; |
|
620 } |
|
621 } |
|
622 |
|
623 immediateArbitration = ETrue; |
|
624 } |
|
625 else |
|
626 { |
|
627 rerr = KErrUnknown; |
|
628 } |
|
629 } |
|
630 }; |
|
631 } |
|
632 |
|
633 // Check if arbitration is required. |
|
634 if(arbitrate && rerr == KErrNone) |
|
635 { |
|
636 rerr = iPhysicalLink->Arbitrate(immediateArbitration, localPriority); |
|
637 } |
|
638 |
|
639 return rerr; |
|
640 } |
|
641 |
|
642 TInt CBTProxySAP::SetModeRequested(TBTLinkMode aMode) |
|
643 { |
|
644 TInt retVal = KErrNotSupported; |
|
645 |
|
646 if(aMode == EActiveMode) |
|
647 { |
|
648 retVal = iRequestedLinkPolicy.SetModeRequested(aMode); |
|
649 } |
|
650 else |
|
651 { |
|
652 if(iLinksMan.LinkManagerProtocol().IsModeSupportedLocally(aMode) && |
|
653 iPhysicalLink->IsModeSupportedRemotely(aMode)) |
|
654 { |
|
655 retVal = iRequestedLinkPolicy.SetModeRequested(aMode); |
|
656 } |
|
657 } |
|
658 return retVal; |
|
659 } |
|
660 |
|
661 TBool CBTProxySAP::CanCreatePhysicalLink() |
|
662 { |
|
663 TBool ret = EFalse; |
|
664 // return ETrue if allowed to create phy |
|
665 if (iPhysicalLink) |
|
666 { |
|
667 // already there! |
|
668 iSocket->ConnectComplete(); |
|
669 } |
|
670 else if(!(Baseband().IsACLPossible())) |
|
671 { |
|
672 iSocket->Error(KErrInsufficientBasebandResources, MSocketNotify::EErrorConnect); |
|
673 } |
|
674 else |
|
675 { |
|
676 ret = ETrue; |
|
677 } |
|
678 return ret; |
|
679 } |
|
680 |
|
681 |
|
682 void CBTProxySAP::ActiveOpen() |
|
683 { |
|
684 // create physical link for bonding |
|
685 TBool proceed = CanCreatePhysicalLink(); |
|
686 if (proceed) |
|
687 { |
|
688 // right, go and connect - no juice on this overload |
|
689 TRAPD(err, iPhysicalLink = &iLinksMan.NewPhysicalLinkL(iRemoteDev)); |
|
690 if(err == KErrNone) |
|
691 { |
|
692 iPhysicalLink->SubscribeProxySAP(*this); |
|
693 iPhysicalLink->Connect(EPagingNormal); |
|
694 } |
|
695 else |
|
696 { |
|
697 iSocket->Error(KErrNoMemory, MSocketNotify::EErrorConnect); |
|
698 } |
|
699 } |
|
700 } |
|
701 |
|
702 void CBTProxySAP::ActiveOpen(const TDesC8& aConnectionToken) |
|
703 { |
|
704 // create physical link for faster connection |
|
705 TBool proceed = CanCreatePhysicalLink(); |
|
706 if (proceed) |
|
707 { |
|
708 // set the cookie |
|
709 TPhysicalLinkQuickConnectionTokenBuf tokenBuf; |
|
710 tokenBuf.Copy(aConnectionToken); |
|
711 |
|
712 TRAPD(err, iPhysicalLink = &iLinksMan.NewPhysicalLinkL(tokenBuf().iDevice)); |
|
713 if(err == KErrNone) |
|
714 { |
|
715 iPhysicalLink->SubscribeProxySAP(*this); |
|
716 iPhysicalLink->Connect(tokenBuf().iPolicy.iPageTimePolicy); // user determines paging policy with their "cookie" |
|
717 } |
|
718 else |
|
719 { |
|
720 iSocket->Error(KErrNoMemory, MSocketNotify::EErrorConnect); |
|
721 } |
|
722 } |
|
723 } |
|
724 |
|
725 TInt CBTProxySAP::PassiveOpen(TUint /*aQueSize*/) |
|
726 { |
|
727 return KErrNotSupported; |
|
728 } |
|
729 |
|
730 TInt CBTProxySAP::PassiveOpen(TUint /*aQueSize*/,const TDesC8& /*aConnectionData*/) |
|
731 { |
|
732 return KErrNotSupported; |
|
733 } |
|
734 |
|
735 void CBTProxySAP::Shutdown(TCloseType aCloseType) |
|
736 { |
|
737 // just our phy to shutdown |
|
738 Shutdown(aCloseType, KDisconnectOnePhysicalLink); |
|
739 } |
|
740 |
|
741 void CBTProxySAP::Shutdown(TCloseType aCloseType,const TDesC8& aDisconnectOption) |
|
742 { |
|
743 |
|
744 //Only ENormal and EImmediate may be used for BaseBand connections |
|
745 __ASSERT_DEBUG((aCloseType == CServProviderBase::ENormal||aCloseType == CServProviderBase::EImmediate),Panic(EBTProxySAPInvalidTerminate)); |
|
746 |
|
747 |
|
748 if (aDisconnectOption == KDisconnectOnePhysicalLink && aCloseType== CServProviderBase::ENormal) |
|
749 { |
|
750 // Unbinding Socket, no additional Caps required |
|
751 // Remove ourselves from the physical SAP - doesnt detach the PHY itself |
|
752 ClearPhysicalLink(); |
|
753 } |
|
754 else |
|
755 { |
|
756 //Atleast one Physical link is to be terminated, any 'Shutdown' on physical |
|
757 //links requires an additional security check for the NetworkControl Cap. |
|
758 //This is required in addition to the LocalServices that was required to create the SAP |
|
759 __ASSERT_DEBUG(iSecurityChecker, User::Panic(KSECURITY_PANIC, EBTPanicNullSecurityChecker)); |
|
760 |
|
761 TInt rerr = iSecurityChecker->CheckPolicy(KNETWORK_CONTROL, KBT_PROXYSAP_NAME_DIAG); |
|
762 if (rerr != KErrNone) |
|
763 { |
|
764 if(iSocket) |
|
765 iSocket->Error(rerr, MSocketNotify::EErrorClose); |
|
766 return; |
|
767 } |
|
768 |
|
769 if (aDisconnectOption == KDisconnectAllPhysicalLinks) |
|
770 { |
|
771 // Disconnecting All BT Physical Links |
|
772 // Only support link *termination*, this is done as normal cos esock weirdness |
|
773 __ASSERT_ALWAYS(aCloseType == CServProviderBase::ENormal, Panic(EBTProxySAPInvalidTerminate)); |
|
774 rerr = iLinksMan.TerminateAllPhysicalLinks(this); |
|
775 LOG2(_L("Proxy SAP 0x%08x -- Terminating all PHY Links, error: %d"), this, rerr); |
|
776 |
|
777 // If there was an error terminating any of the physical links then we can |
|
778 // call CanClose straight away, otherwise this is done when iLinksMan calls |
|
779 // TerminatePhysicalLinksComplete() |
|
780 if (rerr == KErrNone) |
|
781 { |
|
782 iTerminating=ETerminatingAllLinks; |
|
783 return; |
|
784 } |
|
785 } |
|
786 else |
|
787 { |
|
788 //Disconnecting only One Physical Link |
|
789 CPhysicalLink* phy2Term = NULL; |
|
790 |
|
791 if (aDisconnectOption == KDisconnectOnePhysicalLink) |
|
792 { |
|
793 // EImmediate Shutdown - Terminate the Physical link |
|
794 phy2Term = iPhysicalLink; |
|
795 } |
|
796 else |
|
797 { |
|
798 // Shutdown on a specific address (a PHY we arent attached to) |
|
799 // again done as normal since esock is weird |
|
800 TBTDevAddr addr(aDisconnectOption); |
|
801 phy2Term = iLinksMan.FindPhysicalLink(addr); |
|
802 } |
|
803 |
|
804 if(phy2Term) |
|
805 { |
|
806 LOG1(_L("Proxy SAP 0x%08x -- Immediate ShutDown, terminate PHY Link"), this); |
|
807 |
|
808 // If EImmediate shutdown then esock doesn't expect us to call CanClose() so |
|
809 // we don't want iLinksMan to let us know when the physical link has been terminated |
|
810 if (aCloseType == CServProviderBase::EImmediate) |
|
811 { |
|
812 rerr = iLinksMan.TerminatePhysicalLink(phy2Term, NULL); |
|
813 } |
|
814 else |
|
815 { |
|
816 rerr = iLinksMan.TerminatePhysicalLink(phy2Term, this); |
|
817 |
|
818 // If there was an error terminating the physical link then we can |
|
819 // call CanClose straight away, otherwise this is done when iLinksMan calls |
|
820 // TerminatePhysicalLinksComplete() |
|
821 if (rerr == KErrNone) |
|
822 { |
|
823 iTerminating=ETerminatingSingleLink; |
|
824 return; |
|
825 } |
|
826 } |
|
827 } |
|
828 else |
|
829 { |
|
830 // Possible race Condition - the phy may have gone anyway |
|
831 LOG1(_L("Proxy SAP 0x%08x -- PHY Link already terminated by other process"), this); |
|
832 } |
|
833 } |
|
834 } |
|
835 |
|
836 // this may change if esock is altered |
|
837 if (aCloseType==CServProviderBase::ENormal) |
|
838 { |
|
839 // Signal that SAP can be deleted |
|
840 iSocket->CanClose(); |
|
841 } |
|
842 // CAREFUL - might be deleted at this point |
|
843 } |
|
844 |
|
845 |
|
846 void CBTProxySAP::AutoBind() |
|
847 { |
|
848 #ifndef PROXY_COMMUNICATES |
|
849 Panic(EBTProxySAPUnexpectedEvent); |
|
850 #endif |
|
851 } |
|
852 |
|
853 #ifdef PROXY_COMMUNICATES |
|
854 TUint CBTProxySAP::Write(const TDesC8& aData,TUint aOptions, TSockAddr* /*aAddr*/) |
|
855 { |
|
856 // we can throw away some of the options - we only allow them to be 8bit |
|
857 __ASSERT_DEBUG(iRawConduit, Panic(EBTProxySAPNotReadyToSendRawData)); |
|
858 if(!iRawConduit) |
|
859 { |
|
860 iSocket->Error(KErrNotReady, MSocketNotify::EErrorSend); |
|
861 return 0; //Indicates write could not be completed |
|
862 } |
|
863 |
|
864 TUint8 flags = static_cast<TUint8>(aOptions); |
|
865 __ASSERT_DEBUG((flags & KPacketPBFlagMask) == 0, Panic(EBTProxyUserAttemptingToTransmitL2CAPDirectData)); |
|
866 if(flags & KPacketPBFlagMask) |
|
867 { |
|
868 iSocket->Error(KErrNotSupported, MSocketNotify::EErrorSend); |
|
869 return 0; //Indicates write could not be completed |
|
870 } |
|
871 |
|
872 // push the data onto the ACL Pool |
|
873 // the ACL Pool in this build has a reserved slot for broadcast (could use flags!) |
|
874 TUint retVal =0; |
|
875 if (iPhysicalLink) |
|
876 { |
|
877 // only allowed to write raw stuff when a phy is in place |
|
878 // mainly our restriction - but definately the case for broadcasting |
|
879 retVal = iRawConduit->Write(aData, flags); |
|
880 if (retVal==0) |
|
881 { |
|
882 iSocket->Error(KErrInUse, MSocketNotify::EErrorSend); |
|
883 } |
|
884 } |
|
885 else |
|
886 { |
|
887 // haven't even got a phy |
|
888 iSocket->Error(KErrNotReady, MSocketNotify::EErrorSend); |
|
889 } |
|
890 |
|
891 return retVal; |
|
892 #else |
|
893 TUint CBTProxySAP::Write(const TDesC8& /*aDesc*/,TUint /*aOptions*/, TSockAddr* /*aAddr*/) |
|
894 { |
|
895 Panic(EBTProxySAPUnexpectedEvent); |
|
896 return 0; |
|
897 #endif |
|
898 } |
|
899 |
|
900 void CBTProxySAP::Timeout(TBasebandTimeout /*aTimeout*/) |
|
901 { |
|
902 // none of interest |
|
903 } |
|
904 |
|
905 TInt CBTProxySAP::CreateRawConduit() |
|
906 { |
|
907 // instatiates the method by which a Proxy can send raw data |
|
908 // expected to be created via a SetOpt call into this |
|
909 __ASSERT_DEBUG(!iRawConduit, Panic(EBTProxySAPRawConduitAlreadyExists)); |
|
910 |
|
911 TInt err = KErrAlreadyExists; |
|
912 |
|
913 if(!iRawConduit) |
|
914 { |
|
915 TRAP(err, iRawConduit = CACLRawConduit::NewL(*this)); |
|
916 } |
|
917 |
|
918 return err; |
|
919 } |
|
920 |
|
921 void CBTProxySAP::DataReceived() |
|
922 { |
|
923 // do we dont know if the socket was interested in the data?! |
|
924 // but we're unreliable, so people get whatever is here |
|
925 |
|
926 // we can check the sock address in getdata and junk if it's not required |
|
927 if (iSocket && iNotifiedUp) |
|
928 { |
|
929 iSocket->NewData(1); |
|
930 } |
|
931 // else drop |
|
932 } |
|
933 |
|
934 void CBTProxySAP::GetData(TDes8& aData,TUint /*aOptions*/,TSockAddr* /*aAddr*/) |
|
935 { |
|
936 // the conduit has data ready for us...get it now |
|
937 __ASSERT_DEBUG(iRawConduit, Panic(EBTProxySAPNoRawConduit)); |
|
938 if(iRawConduit) |
|
939 { |
|
940 iRawConduit->GetData(aData); |
|
941 } |
|
942 } |
|
943 |
|
944 TBool CBTProxySAP::IsModeRequested(TBTLinkMode aMode) const |
|
945 { |
|
946 return !(iRequestedLinkPolicy.IsModeRequested(aMode)); |
|
947 } |
|
948 |
|
949 TBool CBTProxySAP::IsAnyModeChangeRequested() const |
|
950 { |
|
951 return iRequestedLinkPolicy.IsAnyModeRequested(); |
|
952 } |
|
953 |
|
954 void CBTProxySAP::AsyncCheckLinkUp() |
|
955 { |
|
956 TCallBack cb(SignalConnectComplete, this); |
|
957 iAsyncCallback->Set(cb); |
|
958 iAsyncCallback->SetPriority(CActive::EPriorityHigh); |
|
959 iAsyncCallback->CallBack(); |
|
960 } |
|
961 |
|
962 /*static*/ TInt CBTProxySAP::SignalConnectComplete(TAny* aCBTProxySAP) |
|
963 /** |
|
964 For breaking synchronous call chain |
|
965 **/ |
|
966 { |
|
967 // if the PhysicalSAP is connected, we should tell the proxy ASAP (asynchronously though!) |
|
968 __ASSERT_ALWAYS(aCBTProxySAP, Panic(EBTProxySAPNullCallback)); |
|
969 |
|
970 CBTProxySAP& p = *static_cast<CBTProxySAP*>(aCBTProxySAP); |
|
971 |
|
972 if (p.iPhysicalLink && p.iPhysicalLink->IsConnected()) |
|
973 { |
|
974 p.iSocket->ConnectComplete(); |
|
975 p.iNotifiedUp = ETrue; |
|
976 // lower priority back - might be useful for other async operations |
|
977 p.iAsyncCallback->SetPriority(CActive::EPriorityStandard); |
|
978 } |
|
979 return EFalse; |
|
980 } |
|
981 |
|
982 void CBTProxySAP::TerminatePhysicalLinksComplete() |
|
983 { |
|
984 iTerminating=ENone; |
|
985 |
|
986 if (iSocket) |
|
987 { |
|
988 // Signal that SAP can be deleted |
|
989 iSocket->CanClose(); |
|
990 } |
|
991 // CAREFUL - might be deleted at this point |
|
992 } |
|
993 |
|
994 void CBTProxySAP::PhysicalLinkUp() |
|
995 { |
|
996 // ah! good! let's tell our socket |
|
997 if (iSocket) |
|
998 { |
|
999 iSocket->ConnectComplete(); |
|
1000 iNotifiedUp = ETrue; |
|
1001 } |
|
1002 } |
|
1003 |
|
1004 void CBTProxySAP::PhysicalLinkDown() |
|
1005 { |
|
1006 if (iSocket && iNotifiedUp) |
|
1007 { |
|
1008 iSocket->Disconnect(); |
|
1009 iNotifiedUp = EFalse; |
|
1010 } |
|
1011 ClearPhysicalLink(); |
|
1012 } |
|
1013 |
|
1014 void CBTProxySAP::PhysicalLinkError(TInt aError) |
|
1015 { |
|
1016 if (iSocket) |
|
1017 { |
|
1018 iSocket->Error(aError, MSocketNotify::EErrorAllOperations); |
|
1019 } |
|
1020 ClearPhysicalLink(); |
|
1021 } |
|
1022 |
|
1023 void CBTProxySAP::PhysicalLinkChange(const TBTBasebandEventNotification& aEvent, CPhysicalLink& /*aPhysicalLink*/) |
|
1024 /** |
|
1025 PHY has notified us of a change - demux here |
|
1026 */ |
|
1027 { |
|
1028 switch(aEvent.EventType()) |
|
1029 { |
|
1030 case ENotifyPhysicalLinkUp: |
|
1031 { |
|
1032 PhysicalLinkUp(); |
|
1033 } |
|
1034 break; |
|
1035 |
|
1036 case ENotifyPhysicalLinkDown: |
|
1037 { |
|
1038 PhysicalLinkDown(); |
|
1039 } |
|
1040 break; |
|
1041 |
|
1042 case ENotifyPhysicalLinkError: |
|
1043 PhysicalLinkError(aEvent.ErrorCode()); |
|
1044 if(iEventNotificationStatus == EEnabledOneShot) |
|
1045 { |
|
1046 iEventNotificationStatus = EDisabled; |
|
1047 } |
|
1048 return; |
|
1049 |
|
1050 default: |
|
1051 break; |
|
1052 }; |
|
1053 |
|
1054 if(iEventNotificationStatus == EEnabledOneShot) |
|
1055 { |
|
1056 TBTBasebandEventNotification event(aEvent.EventType() & iBasebandNotifyOptions, aEvent.ErrorCode()); |
|
1057 if(event.EventType()) |
|
1058 { |
|
1059 TBTBasebandEvent pkcgEvent(event); |
|
1060 IoctlComplete(KErrNone, KSolBtLMProxy, KLMBasebandEventOneShotNotificationIoctl, &pkcgEvent); |
|
1061 |
|
1062 iEventNotificationStatus = EDisabled; |
|
1063 } |
|
1064 } |
|
1065 |
|
1066 else if(iEventNotificationStatus != EDisabled) |
|
1067 { |
|
1068 TBTBasebandEventNotification event(aEvent.EventType() & iBasebandNotifyOptions, aEvent.ErrorCode()); |
|
1069 if(event.EventType()) |
|
1070 { |
|
1071 if(iEventNotificationQueue.IsEmpty() && iEventNotificationStatus == EEnabledCanSend) |
|
1072 { |
|
1073 // The queue is empty. Send the event now. |
|
1074 TBTBasebandEvent pkcgEvent(event); |
|
1075 IoctlComplete(KErrNone, KSolBtLMProxy, KLMBasebandEventNotificationIoctl, &pkcgEvent); |
|
1076 |
|
1077 iEventNotificationStatus = EEnabledQueuing; |
|
1078 } |
|
1079 else |
|
1080 { |
|
1081 TBTQueuedBasebandEventNotification* e = new TBTQueuedBasebandEventNotification(event); |
|
1082 if (e) |
|
1083 { |
|
1084 iEventNotificationQueue.AddLast(*e); |
|
1085 } |
|
1086 } |
|
1087 } |
|
1088 } |
|
1089 } |
|
1090 |
|
1091 TUint8 CBTProxySAP::GetRequestedModes() const |
|
1092 { |
|
1093 return iRequestedLinkPolicy.CurrentModeRequest(); |
|
1094 } |
|
1095 |
|
1096 TUint8 CBTProxySAP::GetAllowedModes() const |
|
1097 { |
|
1098 return iRequestedLinkPolicy.ModesAllowed(); |
|
1099 } |
|
1100 |
|
1101 TBool CBTProxySAP::IsRoleSwitchAllowed() const |
|
1102 { |
|
1103 return iRequestedLinkPolicy.IsSwitchAllowed(); |
|
1104 } |
|
1105 |
|
1106 TBool CBTProxySAP::RequestedActiveMode() const |
|
1107 { |
|
1108 return iRequestedActiveMode; |
|
1109 } |
|
1110 |
|
1111 TRequestedLinkPolicy::TRequestedLinkPolicy(TUint8 aModesAllowed, TBool aSwitchAllowed) |
|
1112 : iSwitchAllowed(aSwitchAllowed), iModesAllowed(aModesAllowed), |
|
1113 iCurrentModeRequest(0) |
|
1114 { |
|
1115 } |
|
1116 |
|
1117 TBool TRequestedLinkPolicy::IsModeAllowed(TBTLinkMode aMode) const |
|
1118 { |
|
1119 TBool allowed = EFalse; |
|
1120 |
|
1121 switch (aMode) |
|
1122 { |
|
1123 case EActiveMode: |
|
1124 allowed = ETrue; |
|
1125 break; |
|
1126 |
|
1127 case EHoldMode: |
|
1128 case ESniffMode: |
|
1129 case EParkMode: |
|
1130 allowed = iModesAllowed & aMode; |
|
1131 break; |
|
1132 |
|
1133 default: |
|
1134 Panic(EBTConnectionUnknownLowPowerMode); |
|
1135 } |
|
1136 return allowed; |
|
1137 } |
|
1138 |
|
1139 TBool TRequestedLinkPolicy::IsSwitchAllowed() const |
|
1140 { |
|
1141 return iSwitchAllowed; |
|
1142 } |
|
1143 |
|
1144 void TRequestedLinkPolicy::SetModeAllowed(TBTLinkMode aMode, TBool aAllowed) |
|
1145 { |
|
1146 switch (aMode) |
|
1147 { |
|
1148 case EHoldMode: |
|
1149 case ESniffMode: |
|
1150 case EParkMode: |
|
1151 aAllowed ? iModesAllowed |= aMode : iModesAllowed &= ~aMode; |
|
1152 break; |
|
1153 default: |
|
1154 Panic(EBTConnectionUnknownLowPowerMode); |
|
1155 } |
|
1156 } |
|
1157 |
|
1158 void TRequestedLinkPolicy::SetSwitchAllowed(TBool aAllowed) |
|
1159 { |
|
1160 iSwitchAllowed = aAllowed; |
|
1161 } |
|
1162 |
|
1163 |
|
1164 TBool TRequestedLinkPolicy::IsModeRequested(TBTLinkMode aMode) const |
|
1165 { |
|
1166 TBool requested = EFalse; |
|
1167 |
|
1168 switch (aMode) |
|
1169 { |
|
1170 case EActiveMode: |
|
1171 case EHoldMode: |
|
1172 case ESniffMode: |
|
1173 case EParkMode: |
|
1174 requested = iCurrentModeRequest & aMode; |
|
1175 break; |
|
1176 |
|
1177 default: |
|
1178 Panic(EBTConnectionUnknownLowPowerMode); |
|
1179 } |
|
1180 return requested; |
|
1181 } |
|
1182 |
|
1183 TBool TRequestedLinkPolicy::IsAnyModeRequested() const |
|
1184 { |
|
1185 return iCurrentModeRequest; |
|
1186 } |
|
1187 |
|
1188 |
|
1189 TInt TRequestedLinkPolicy::SetModeRequested(TBTLinkMode aMode) |
|
1190 { |
|
1191 switch (aMode) |
|
1192 { |
|
1193 case EActiveMode: |
|
1194 case EHoldMode: |
|
1195 case ESniffMode: |
|
1196 case EParkMode: |
|
1197 iCurrentModeRequest = TUint8(aMode); |
|
1198 break; |
|
1199 |
|
1200 default: |
|
1201 Panic(EBTConnectionUnknownLowPowerMode); |
|
1202 } |
|
1203 return KErrNone; |
|
1204 } |
|
1205 |
|
1206 TUint8 TRequestedLinkPolicy::ModesAllowed() const |
|
1207 { |
|
1208 return iModesAllowed; |
|
1209 } |
|
1210 |
|
1211 TUint8 TRequestedLinkPolicy::CurrentModeRequest() const |
|
1212 { |
|
1213 return iCurrentModeRequest; |
|
1214 } |