|
1 /* |
|
2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Helper class implementation for performing device discovery. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "btengdevicesearch.h" |
|
20 #include "btengdiscovery.h" |
|
21 #include "debug.h" |
|
22 |
|
23 /** |
|
24 * the request ID for device search using RNotifer. |
|
25 */ |
|
26 const TInt KDevSearchAoReqId = 40; |
|
27 |
|
28 /* |
|
29 * the request ID for EIR service uuids using host resolver |
|
30 */ |
|
31 const TInt KDevEirServiceListAoReqId = 41; |
|
32 |
|
33 // ======== MEMBER FUNCTIONS ======== |
|
34 |
|
35 // --------------------------------------------------------------------------- |
|
36 // C++ default constructor |
|
37 // --------------------------------------------------------------------------- |
|
38 // |
|
39 CBTEngDeviceSearch::CBTEngDeviceSearch() |
|
40 { |
|
41 } |
|
42 |
|
43 |
|
44 // --------------------------------------------------------------------------- |
|
45 // Symbian 2nd-phase constructor |
|
46 // --------------------------------------------------------------------------- |
|
47 // |
|
48 void CBTEngDeviceSearch::ConstructL() |
|
49 { |
|
50 User::LeaveIfError( iNotifier.Connect() ); |
|
51 iActive = CBTEngActive::NewL( *this, KDevSearchAoReqId, |
|
52 CActive::EPriorityStandard ); |
|
53 } |
|
54 |
|
55 |
|
56 // --------------------------------------------------------------------------- |
|
57 // NewL |
|
58 // --------------------------------------------------------------------------- |
|
59 // |
|
60 CBTEngDeviceSearch* CBTEngDeviceSearch::NewL() |
|
61 { |
|
62 CBTEngDeviceSearch* self = new( ELeave ) CBTEngDeviceSearch(); |
|
63 CleanupStack::PushL( self ); |
|
64 self->ConstructL(); |
|
65 CleanupStack::Pop( self ); |
|
66 return self; |
|
67 } |
|
68 |
|
69 // --------------------------------------------------------------------------- |
|
70 // Destructor |
|
71 // --------------------------------------------------------------------------- |
|
72 // |
|
73 CBTEngDeviceSearch::~CBTEngDeviceSearch() |
|
74 { |
|
75 if( iNotifier.Handle()&& iActive->IsActive()) |
|
76 { |
|
77 iNotifier.CancelNotifier( KDeviceSelectionNotifierUid ); |
|
78 iActive->CancelRequest(); |
|
79 } |
|
80 delete iActive; |
|
81 iNotifier.Close(); |
|
82 iHostResolver.Close(); |
|
83 iSocketServer.Close(); |
|
84 } |
|
85 |
|
86 // --------------------------------------------------------------------------- |
|
87 // Start the device discovery notifier. |
|
88 // --------------------------------------------------------------------------- |
|
89 // |
|
90 TInt CBTEngDeviceSearch::StartSearch( CBTDevice* aDevice, TNameEntry* aNameEntry, |
|
91 const TBTDeviceClass& aDeviceClass, MBTEngSdpResultReceiver* aNotifier ) |
|
92 { |
|
93 TRACE_FUNC_ENTRY |
|
94 TInt err ( KErrNone ); |
|
95 if( iActive->IsActive() ) |
|
96 { |
|
97 err = KErrInUse; |
|
98 } |
|
99 if( !err && !iNotifier.Handle() ) |
|
100 { |
|
101 err = iNotifier.Connect(); |
|
102 } |
|
103 if( !err ) |
|
104 { |
|
105 iClientReq = EDeviceSearch; |
|
106 iResultNotifier = aNotifier; |
|
107 iNameEntry = aNameEntry; |
|
108 iDevice = aDevice; |
|
109 // Selection parameters |
|
110 TBTDeviceSelectionParams params; |
|
111 params.SetDeviceClass( aDeviceClass ); |
|
112 iSelectionPckg = TBTDeviceSelectionParamsPckg( params ); |
|
113 // Response parameters |
|
114 TBTDeviceResponseParams result; |
|
115 iResponsePckg = TBTDeviceResponseParamsPckg( result ); |
|
116 iActive->SetRequestId( KDevSearchAoReqId ); |
|
117 iNotifier.StartNotifierAndGetResponse( iActive->RequestStatus(), |
|
118 KDeviceSelectionNotifierUid, |
|
119 iSelectionPckg, iResponsePckg ); |
|
120 iActive->GoActive(); |
|
121 } |
|
122 TRACE_FUNC_EXIT |
|
123 return err; |
|
124 } |
|
125 |
|
126 // --------------------------------------------------------------------------- |
|
127 // Cancel an ongoing device discovery. |
|
128 // --------------------------------------------------------------------------- |
|
129 // |
|
130 void CBTEngDeviceSearch::CancelSearch() |
|
131 { |
|
132 TRACE_FUNC_ENTRY |
|
133 if( iActive->IsActive() && iClientReq == EDeviceSearch) |
|
134 { |
|
135 if (iActive->RequestId() == KDevSearchAoReqId) |
|
136 { |
|
137 iNotifier.CancelNotifier( KDeviceSelectionNotifierUid ); |
|
138 iActive->CancelRequest(); |
|
139 iNotifier.Close(); |
|
140 NotifyClient(KErrAbort); |
|
141 } |
|
142 else if (iActive->RequestId() == KDevEirServiceListAoReqId) |
|
143 { |
|
144 iHostResolver.Cancel(); |
|
145 iHostResolver.Close(); |
|
146 } |
|
147 } |
|
148 |
|
149 TRACE_FUNC_EXIT |
|
150 } |
|
151 |
|
152 // --------------------------------------------------------------------------- |
|
153 // Get cached EIR data from host resolver and extract service uuids |
|
154 // --------------------------------------------------------------------------- |
|
155 // |
|
156 TInt CBTEngDeviceSearch::GetEirServiceUUIDs( const TBTDevAddr& aAddr, |
|
157 TNameEntry* aNameEntry, MBTEngSdpResultReceiver* aNotifier) |
|
158 { |
|
159 TRACE_FUNC_ENTRY |
|
160 TInt err = KErrNone; |
|
161 if( iActive->IsActive() ) |
|
162 { |
|
163 err = KErrInUse; |
|
164 } |
|
165 if (!err) |
|
166 { |
|
167 iClientReq = EGetDeviceEir; |
|
168 iResultNotifier = aNotifier; |
|
169 iNameEntry = aNameEntry; |
|
170 err = DoGetDeviceEir(aAddr); |
|
171 } |
|
172 TRACE_FUNC_EXIT |
|
173 return err; |
|
174 } |
|
175 |
|
176 // --------------------------------------------------------------------------- |
|
177 // Cancel an ongoing EIR services retieval. |
|
178 // --------------------------------------------------------------------------- |
|
179 // |
|
180 void CBTEngDeviceSearch::CancelGetEirServiceUUIDs() |
|
181 { |
|
182 TRACE_FUNC_ENTRY |
|
183 if( iActive->IsActive() && iClientReq == EGetDeviceEir) |
|
184 { |
|
185 iHostResolver.Cancel(); |
|
186 iHostResolver.Close(); |
|
187 } |
|
188 TRACE_FUNC_EXIT |
|
189 } |
|
190 |
|
191 // --------------------------------------------------------------------------- |
|
192 // From class MBTEngActiveObserver. |
|
193 // Callback to notify that an outstanding request has completed. |
|
194 // --------------------------------------------------------------------------- |
|
195 // |
|
196 void CBTEngDeviceSearch::RequestCompletedL( CBTEngActive* aActive, TInt aId, |
|
197 TInt aStatus ) |
|
198 { |
|
199 TRACE_FUNC_ARG( ( _L( "status: %d") , aStatus ) ) |
|
200 (void) aActive; |
|
201 if ( aId == KDevSearchAoReqId ) |
|
202 { |
|
203 HandleDeviceSelectionResultL(aStatus); |
|
204 } |
|
205 else if (aId == KDevEirServiceListAoReqId) |
|
206 { |
|
207 HandleDeviceEirDataResult( aStatus ); |
|
208 } |
|
209 TRACE_FUNC_EXIT |
|
210 } |
|
211 |
|
212 // --------------------------------------------------------------------------- |
|
213 // From class MBTEngActiveObserver. |
|
214 // Callback to notify that an error has occurred in RunL. |
|
215 // --------------------------------------------------------------------------- |
|
216 // |
|
217 void CBTEngDeviceSearch::HandleError( CBTEngActive* aActive, TInt aId, |
|
218 TInt aError ) |
|
219 { |
|
220 TRACE_FUNC_ARG( ( _L( "error: %d") , aError ) ) |
|
221 (void) aActive; |
|
222 (void) aId; |
|
223 iNotifier.Close(); |
|
224 iHostResolver.Close(); |
|
225 NotifyClient(aError); |
|
226 } |
|
227 |
|
228 // --------------------------------------------------------------------------- |
|
229 // get device eir from cache |
|
230 // --------------------------------------------------------------------------- |
|
231 // |
|
232 TInt CBTEngDeviceSearch::DoGetDeviceEir(const TBTDevAddr& aAddr) |
|
233 { |
|
234 TRACE_FUNC_ENTRY |
|
235 TInt err (KErrNone); |
|
236 if (!iSocketServer.Handle()) |
|
237 { |
|
238 err = iSocketServer.Connect(); |
|
239 } |
|
240 |
|
241 TProtocolDesc pInfo; |
|
242 if (!err) |
|
243 { |
|
244 _LIT(KBTLinkManagerProtocol, "BTLinkManager"); |
|
245 err = iSocketServer.FindProtocol( KBTLinkManagerProtocol(), pInfo ); |
|
246 } |
|
247 if (!err) |
|
248 { |
|
249 err = iHostResolver.Open(iSocketServer, pInfo.iAddrFamily, pInfo.iProtocol); |
|
250 } |
|
251 if( !err ) |
|
252 { |
|
253 iInquirySockAddr = TInquirySockAddr(); |
|
254 iInquirySockAddr.SetBTAddr(aAddr ); |
|
255 iInquirySockAddr.SetAction( KHostResCache ); |
|
256 iActive->SetRequestId( KDevEirServiceListAoReqId ); |
|
257 iHostResolver.GetByAddress( iInquirySockAddr, *iNameEntry, iActive->RequestStatus() ); |
|
258 iActive->GoActive(); |
|
259 } |
|
260 TRACE_FUNC_EXIT |
|
261 return err; |
|
262 } |
|
263 |
|
264 void CBTEngDeviceSearch::HandleDeviceSelectionResultL(TInt aErr) |
|
265 { |
|
266 TRACE_FUNC_ENTRY |
|
267 TInt err (aErr); |
|
268 iNotifier.Close(); |
|
269 if (!err) |
|
270 { |
|
271 // Copy information to returned device |
|
272 iDevice->SetDeviceAddress( iResponsePckg().BDAddr() ); |
|
273 iDevice->SetDeviceNameL( BTDeviceNameConverter::ToUTF8L( |
|
274 iResponsePckg().DeviceName() ) ); |
|
275 iDevice->SetDeviceClass( iResponsePckg().DeviceClass() ); |
|
276 } |
|
277 if (!err && iNameEntry) |
|
278 { |
|
279 err = DoGetDeviceEir(iResponsePckg().BDAddr()); |
|
280 } |
|
281 // if an error happens, or the caller doesn't need the EIR part, complete |
|
282 // the request. Otherwise the client will be called after getting EIR |
|
283 // completes. |
|
284 if (err || !iNameEntry) |
|
285 { |
|
286 NotifyClient(err); |
|
287 } |
|
288 TRACE_FUNC_EXIT |
|
289 } |
|
290 |
|
291 // --------------------------------------------------------------------------- |
|
292 // extracting service uuids from the device EIR data returned by host resolver |
|
293 // --------------------------------------------------------------------------- |
|
294 // |
|
295 void CBTEngDeviceSearch::HandleDeviceEirDataResult(TInt aErr) |
|
296 { |
|
297 TRACE_FUNC_ENTRY |
|
298 iHostResolver.Close(); |
|
299 |
|
300 if ( iClientReq == EDeviceSearch) |
|
301 { |
|
302 // Device search has already completed correctly, so |
|
303 // we don't pass GetEir error |
|
304 NotifyClient( KErrNone ); |
|
305 } |
|
306 else |
|
307 { |
|
308 NotifyClient( aErr ); |
|
309 } |
|
310 TRACE_FUNC_EXIT |
|
311 } |
|
312 |
|
313 // --------------------------------------------------------------------------- |
|
314 // Callback to notify that the caller's request has completed. |
|
315 // --------------------------------------------------------------------------- |
|
316 // |
|
317 void CBTEngDeviceSearch::NotifyClient(TInt aErr) |
|
318 { |
|
319 TRACE_FUNC_ENTRY |
|
320 if( iResultNotifier && iClientReq == EDeviceSearch) |
|
321 { |
|
322 if (iNameEntry) |
|
323 { |
|
324 iResultNotifier->DeviceSearchComplete( iDevice, iNameEntry, aErr ); |
|
325 } |
|
326 else |
|
327 { |
|
328 iResultNotifier->DeviceSearchComplete( iDevice, aErr ); |
|
329 } |
|
330 } |
|
331 if (iResultNotifier && iClientReq == EGetDeviceEir) |
|
332 { |
|
333 iResultNotifier->GetEirServiceUUIDsComplete(iNameEntry, aErr); |
|
334 } |
|
335 TRACE_FUNC_EXIT |
|
336 } |
|
337 |