|
1 // Copyright (c) 2008-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 // |
|
15 |
|
16 #include <bt_sock.h> |
|
17 #include "physicallinkmetrichelpers.h" |
|
18 |
|
19 _LIT(KPhysLinkMetricFaultCat, "BTPhysLinkMetric"); |
|
20 enum TPhysLinkMetricFault |
|
21 { |
|
22 EInvalidMetric, |
|
23 }; |
|
24 |
|
25 /** |
|
26 Creates a new CBluetoothPhysicalLinkMetrics object from a connected socket |
|
27 @param aObserver The object which will receive asynchronous events |
|
28 @param aSockServ A handle to an existing session on the socket server (ESock). |
|
29 @param aConnectedSocket An open connected socket (ESock subsession) on that existing ESock session |
|
30 */ |
|
31 EXPORT_C CBluetoothPhysicalLinkMetrics* CBluetoothPhysicalLinkMetrics::NewL( |
|
32 MBluetoothPhysicalLinkMetricsObserver& aObserver, |
|
33 RSocketServ& aSockServ, |
|
34 RSocket& aConnectedSocket) |
|
35 { |
|
36 CBluetoothPhysicalLinkMetrics* self = new(ELeave) CBluetoothPhysicalLinkMetrics(aObserver); |
|
37 CleanupStack::PushL(self); |
|
38 self->ConstructL(aSockServ, aConnectedSocket); |
|
39 CleanupStack::Pop(self); |
|
40 return self; |
|
41 } |
|
42 |
|
43 /** |
|
44 Creates a new CBluetoothPhysicalLinkMetrics object from a connected socket |
|
45 @param aObserver The object which will receive asynchronous events |
|
46 @param aSockServ A handle to an existing session on the socket server (ESock). |
|
47 @param aAddr The Bluetooth address of a remote device with which there is an existing connection |
|
48 */ |
|
49 EXPORT_C CBluetoothPhysicalLinkMetrics* CBluetoothPhysicalLinkMetrics::NewL( |
|
50 MBluetoothPhysicalLinkMetricsObserver& aObserver, |
|
51 RSocketServ& aSockServ, |
|
52 const TBTDevAddr& aAddr) |
|
53 { |
|
54 CBluetoothPhysicalLinkMetrics* self = new(ELeave) CBluetoothPhysicalLinkMetrics(aObserver); |
|
55 CleanupStack::PushL(self); |
|
56 self->ConstructL(aSockServ, aAddr); |
|
57 CleanupStack::Pop(self); |
|
58 return self; |
|
59 } |
|
60 |
|
61 /** |
|
62 Destructor |
|
63 */ |
|
64 EXPORT_C CBluetoothPhysicalLinkMetrics::~CBluetoothPhysicalLinkMetrics() |
|
65 { |
|
66 delete iRssiBaseband; |
|
67 delete iLinkQualityBaseband; |
|
68 delete iFailedContactCounterBaseband; |
|
69 delete iTransmitPowerLevelBaseband; |
|
70 } |
|
71 |
|
72 /** |
|
73 Subscribes for notification of changes to the RSSI (Received Signal Strengh Indication) |
|
74 of the link. |
|
75 MBluetoothPhysicalLinkMetricsObserver::MbplmoRssiChanged will be called with the |
|
76 initial value, then subsequently every time the RSSI changes, subject to the polling |
|
77 interval specified in the stack. |
|
78 The stack will continue to run a timer to poll the hardware until the physical link is disconnected |
|
79 or CBluetoothPhysicalLinkMetrics::Cancel is called |
|
80 */ |
|
81 EXPORT_C void CBluetoothPhysicalLinkMetrics::SubscribeRssi() |
|
82 { |
|
83 iRssiBaseband->SubscribePhysicalLinkMetric(KLMReadRssiIoctl); |
|
84 } |
|
85 |
|
86 /** |
|
87 Subscribes for notification of changes to the Link Quality. |
|
88 MBluetoothPhysicalLinkMetricsObserver::MbplmoLinkQualityChanged will be called with the |
|
89 initial value, then subsequently every time the link quality changes, subject to the |
|
90 polling interval specified in the stack. |
|
91 The stack will continue to run a timer to poll the hardware until the physical link is disconnected |
|
92 or CBluetoothPhysicalLinkMetrics::Cancel is called |
|
93 */ |
|
94 EXPORT_C void CBluetoothPhysicalLinkMetrics::SubscribeLinkQuality() |
|
95 { |
|
96 iLinkQualityBaseband->SubscribePhysicalLinkMetric(KLMReadLinkQualityIoctl); |
|
97 } |
|
98 |
|
99 /** |
|
100 Subscribes for notification of changes to the Failed Contact counter of the link. |
|
101 MBluetoothPhysicalLinkMetricsObserver::MbplmoFailedContactCounterChanged will be called |
|
102 with the initial value, then subsequently every time the failed contact counter changes, |
|
103 subject to the polling interval specified in the stack. |
|
104 The stack will continue to run a timer to poll the hardware until the physical link is disconnected |
|
105 or CBluetoothPhysicalLinkMetrics::Cancel is called |
|
106 */ |
|
107 EXPORT_C void CBluetoothPhysicalLinkMetrics::SubscribeFailedContactCounter() |
|
108 { |
|
109 iFailedContactCounterBaseband->SubscribePhysicalLinkMetric(KLMReadFailedContactCounterIoctl); |
|
110 } |
|
111 |
|
112 /** |
|
113 Subscribes for notification of changes to the Transmit Power Level of the link. |
|
114 MBluetoothPhysicalLinkMetricsObserver::MbplmoTransmitPowerLevelChanged will be called |
|
115 with the initial value, then subsequently every time the transmit power level changes, |
|
116 subject to the polling interval specified in the stack. |
|
117 The stack will continue to run a timer to poll the hardware until the physical link is disconnected |
|
118 or CBluetoothPhysicalLinkMetrics::Cancel is called |
|
119 */ |
|
120 EXPORT_C void CBluetoothPhysicalLinkMetrics::SubscribeTransmitPowerLevel() |
|
121 { |
|
122 iTransmitPowerLevelBaseband->SubscribePhysicalLinkMetric(KLMReadCurrentTransmitPowerLevelIoctl); |
|
123 } |
|
124 |
|
125 /** |
|
126 Cancels subscriptions to all physical link notifications. |
|
127 */ |
|
128 EXPORT_C void CBluetoothPhysicalLinkMetrics::Cancel() |
|
129 { |
|
130 iRssiBaseband->Cancel(); |
|
131 iLinkQualityBaseband->Cancel(); |
|
132 iTransmitPowerLevelBaseband->Cancel(); |
|
133 iFailedContactCounterBaseband->Cancel(); |
|
134 } |
|
135 |
|
136 void CBluetoothPhysicalLinkMetrics::RssiChanged(TInt8 aRssi) |
|
137 { |
|
138 iObserver.MbplmoRssiChanged(aRssi); |
|
139 } |
|
140 |
|
141 void CBluetoothPhysicalLinkMetrics::LinkQualityChanged(TUint8 aLinkQuality) |
|
142 { |
|
143 iObserver.MbplmoLinkQualityChanged(aLinkQuality); |
|
144 } |
|
145 |
|
146 void CBluetoothPhysicalLinkMetrics::FailedContactCounterChanged(TUint16 aFailedContactCounter) |
|
147 { |
|
148 iObserver.MbplmoFailedContactCounterChanged(aFailedContactCounter); |
|
149 } |
|
150 |
|
151 void CBluetoothPhysicalLinkMetrics::TransmitPowerLevelChanged(TInt8 aTransmitPowerLevel) |
|
152 { |
|
153 iObserver.MbplmoTransmitPowerLevelChanged(aTransmitPowerLevel); |
|
154 } |
|
155 |
|
156 void CBluetoothPhysicalLinkMetrics::SubscribeError(TInt aError) |
|
157 { |
|
158 Cancel(); |
|
159 iObserver.MbplmoError(aError); |
|
160 } |
|
161 |
|
162 CBluetoothPhysicalLinkMetrics::CBluetoothPhysicalLinkMetrics(MBluetoothPhysicalLinkMetricsObserver& aObserver): |
|
163 iObserver(aObserver) |
|
164 { |
|
165 |
|
166 } |
|
167 template <class T> |
|
168 void CBluetoothPhysicalLinkMetrics::ConstructL(RSocketServ& aSockServ, T& aLinkIdentifier) |
|
169 { |
|
170 iRssiBaseband = CBluetoothPhysicalLinkMetricSubscriber::NewL(*this, aSockServ, aLinkIdentifier); |
|
171 iLinkQualityBaseband = CBluetoothPhysicalLinkMetricSubscriber::NewL(*this, aSockServ, aLinkIdentifier); |
|
172 iFailedContactCounterBaseband = CBluetoothPhysicalLinkMetricSubscriber::NewL(*this, aSockServ, aLinkIdentifier); |
|
173 iTransmitPowerLevelBaseband = CBluetoothPhysicalLinkMetricSubscriber::NewL(*this, aSockServ, aLinkIdentifier); |
|
174 } |
|
175 |
|
176 CBluetoothPhysicalLinkMetricSubscriber* CBluetoothPhysicalLinkMetricSubscriber::NewL( |
|
177 CBluetoothPhysicalLinkMetrics& aParent, |
|
178 RSocketServ& aSockServ, |
|
179 RSocket& aConnectedSocket) |
|
180 { |
|
181 CBluetoothPhysicalLinkMetricSubscriber* self = new(ELeave) CBluetoothPhysicalLinkMetricSubscriber(aParent); |
|
182 CleanupStack::PushL(self); |
|
183 self->ConstructL(aSockServ, aConnectedSocket); |
|
184 CleanupStack::Pop(self); |
|
185 return self; |
|
186 |
|
187 } |
|
188 |
|
189 CBluetoothPhysicalLinkMetricSubscriber* CBluetoothPhysicalLinkMetricSubscriber::NewL( |
|
190 CBluetoothPhysicalLinkMetrics& aParent, |
|
191 RSocketServ& aSockServ, |
|
192 const TBTDevAddr& aAddr) |
|
193 { |
|
194 CBluetoothPhysicalLinkMetricSubscriber* self = new(ELeave) CBluetoothPhysicalLinkMetricSubscriber(aParent); |
|
195 CleanupStack::PushL(self); |
|
196 self->ConstructL(aSockServ, aAddr); |
|
197 CleanupStack::Pop(self); |
|
198 return self; |
|
199 } |
|
200 |
|
201 CBluetoothPhysicalLinkMetricSubscriber::~CBluetoothPhysicalLinkMetricSubscriber() |
|
202 { |
|
203 Cancel(); |
|
204 iBaseband.Close(); |
|
205 } |
|
206 |
|
207 void CBluetoothPhysicalLinkMetricSubscriber::SubscribePhysicalLinkMetric(TBTLMIoctls aIoctl) |
|
208 { |
|
209 if (!IsActive()) |
|
210 { |
|
211 iPhysicalLinkMetric = aIoctl; |
|
212 iValue() = KMaxTInt; |
|
213 // KMaxTInt is not a valid value that will be returned by the controller, so this is used |
|
214 // as a value to get the initial value from the stack. |
|
215 iBaseband.ReadNewPhysicalLinkMetricValue(iStatus, iValue, iPhysicalLinkMetric); |
|
216 SetActive(); |
|
217 } |
|
218 } |
|
219 |
|
220 |
|
221 CBluetoothPhysicalLinkMetricSubscriber::CBluetoothPhysicalLinkMetricSubscriber(CBluetoothPhysicalLinkMetrics& aParent): |
|
222 CActive(CActive::EPriorityStandard), iParent(aParent) |
|
223 { |
|
224 CActiveScheduler::Add(this); |
|
225 } |
|
226 |
|
227 void CBluetoothPhysicalLinkMetricSubscriber::ConstructL(RSocketServ& aSockServ, RSocket& aConnectedSocket) |
|
228 { |
|
229 User::LeaveIfError(iBaseband.Open(aSockServ, aConnectedSocket)); |
|
230 } |
|
231 |
|
232 void CBluetoothPhysicalLinkMetricSubscriber::ConstructL(RSocketServ& aSockServ, const TBTDevAddr& aAddr) |
|
233 { |
|
234 User::LeaveIfError(iBaseband.Open(aSockServ, const_cast<TBTDevAddr&>(aAddr))); |
|
235 } |
|
236 |
|
237 void CBluetoothPhysicalLinkMetricSubscriber::RunL() |
|
238 { |
|
239 User::LeaveIfError(iStatus.Int()); |
|
240 iBaseband.ReadNewPhysicalLinkMetricValue(iStatus, iValue, iPhysicalLinkMetric); |
|
241 SetActive(); |
|
242 switch (iPhysicalLinkMetric) |
|
243 { |
|
244 case KLMReadRssiIoctl: |
|
245 iParent.RssiChanged(iValue()); |
|
246 break; |
|
247 case KLMReadCurrentTransmitPowerLevelIoctl: |
|
248 iParent.TransmitPowerLevelChanged(iValue()); |
|
249 break; |
|
250 case KLMReadLinkQualityIoctl: |
|
251 iParent.LinkQualityChanged(iValue()); |
|
252 break; |
|
253 case KLMReadFailedContactCounterIoctl: |
|
254 iParent.FailedContactCounterChanged(iValue()); |
|
255 break; |
|
256 default: |
|
257 __ASSERT_ALWAYS(EFalse,User::Panic(KPhysLinkMetricFaultCat, EInvalidMetric)); |
|
258 } |
|
259 } |
|
260 |
|
261 TInt CBluetoothPhysicalLinkMetricSubscriber::RunError(TInt aError) |
|
262 { |
|
263 iParent.SubscribeError(aError); |
|
264 return KErrNone; |
|
265 } |
|
266 |
|
267 void CBluetoothPhysicalLinkMetricSubscriber::DoCancel() |
|
268 { |
|
269 iBaseband.CancelPhysicalLinkMetricUpdate(); |
|
270 } |
|
271 |
|
272 EXPORT_C TAny* MBluetoothPhysicalLinkMetricsObserver::MbplmoExtensionInterfaceL(TUid /* aInterface */) |
|
273 { |
|
274 User::Leave(KErrExtensionNotSupported); |
|
275 return NULL; |
|
276 } |