|
1 /* |
|
2 * Copyright (c) 2009 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: Part of CBTInqUI class: use Active object to search BT devices. |
|
15 * |
|
16 */ |
|
17 #include "btninqui.h" |
|
18 #include "btNotifDebug.h" |
|
19 |
|
20 /** Identification for active object request */ |
|
21 const TInt KBTNotifInquiryNotifierReq = 20; |
|
22 |
|
23 // ---------------------------------------------------------- |
|
24 // CBTInqUI::PrepareScannerL |
|
25 // ---------------------------------------------------------- |
|
26 // |
|
27 void CBTInqUI::CreateScannerL() |
|
28 { |
|
29 FLOG(_L("[BTNOTIF]\t CBTInqUI::CreateScannerL()")); |
|
30 |
|
31 __ASSERT_DEBUG( iScanner == NULL, User::Panic(_L("BTNotifInqUI - iScanner not released!"),KErrAlreadyExists)); |
|
32 |
|
33 // Create scanner object which will do the actual search |
|
34 iScanner = CBTNotifActive::NewL( this, KBTNotifInquiryNotifierReq, CActive::EPriorityStandard ); |
|
35 User::LeaveIfError( iSocketServer.Connect() ); |
|
36 TProtocolDesc pInfo; |
|
37 User::LeaveIfError( iSocketServer.FindProtocol( _L("BTLinkManager"), pInfo)); |
|
38 User::LeaveIfError( iHostResolver.Open(iSocketServer, pInfo.iAddrFamily, pInfo.iProtocol)); |
|
39 IssueRequestL(); |
|
40 |
|
41 FLOG(_L("[BTNOTIF]\t CBTInqUI::CreateScannerL() completed")); |
|
42 } |
|
43 |
|
44 // ---------------------------------------------------------- |
|
45 // CBTInqUI::IssueRequestL |
|
46 // Issue Bluetooth device inquiry/search itself. |
|
47 // Reads also inquiry mode from shared data. |
|
48 // ---------------------------------------------------------- |
|
49 // |
|
50 void CBTInqUI::IssueRequestL() |
|
51 { |
|
52 FLOG(_L("[BTNOTIF]\t CBTInqUI::IssueRequestL()")); |
|
53 |
|
54 if (reinterpret_cast<CBTNotifierBase*>(iDevSearchObserver)->AutoLockOnL()) |
|
55 { |
|
56 // Cancel bt inquiry immediately if device is locked. |
|
57 FLOG(_L("[BTNOTIF]\t CBTInqUI::IssueRequestL() Device is locked")); |
|
58 Cancel(); |
|
59 return; |
|
60 } |
|
61 |
|
62 TUint action = 0; |
|
63 if( !iPageForName ) |
|
64 { |
|
65 action = KHostResInquiry + KHostResEir + KHostResIgnoreCache; |
|
66 } |
|
67 else |
|
68 { |
|
69 TInt firstPartialNameDevIndex; |
|
70 if (HaveDevsWithPartialName(firstPartialNameDevIndex)) |
|
71 { |
|
72 FTRACE(FPrint(_L("[BTNOTIF]\t CBTInqUI::IssueRequestL() looking up device index %d (have partial name already)"), firstPartialNameDevIndex)); |
|
73 |
|
74 action = KHostResName + KHostResIgnoreCache; |
|
75 TInquirySockAddr sa; |
|
76 sa.SetBTAddr(iLastSeenDevicesArray->At(firstPartialNameDevIndex)->BDAddr()); |
|
77 iInquirySockAddr.SetBTAddr( sa.BTAddr() ); |
|
78 } |
|
79 else if( iCurrentlyResolvingUnnamedDeviceIndex < iDevsWithoutName.Count() ) |
|
80 { |
|
81 FTRACE(FPrint(_L("[BTNOTIF]\t CBTInqUI::IssueRequestL() looking up device index %d (currently anonymous)"), iCurrentlyResolvingUnnamedDeviceIndex)); |
|
82 |
|
83 action = KHostResName + KHostResIgnoreCache; |
|
84 TInquirySockAddr& sa = TInquirySockAddr::Cast( iDevsWithoutName[iCurrentlyResolvingUnnamedDeviceIndex].iAddr ); |
|
85 iInquirySockAddr.SetBTAddr( sa.BTAddr() ); |
|
86 } |
|
87 } |
|
88 if (action) |
|
89 { |
|
90 iInquirySockAddr.SetAction( action ); |
|
91 iInquirySockAddr.SetIAC(KGIAC); |
|
92 iHostResolver.GetByAddress( iInquirySockAddr, iEntry, iScanner->RequestStatus() ); |
|
93 iScanner->GoActive(); |
|
94 } |
|
95 else |
|
96 { |
|
97 FLOG(_L("[BTNOTIF]\t CBTInqUI::RunL() All name inquiries complete .")); |
|
98 iPageForName = EFalse; |
|
99 iCurrentlyResolvingUnnamedDeviceIndex = 0; |
|
100 InquiryComplete( KErrNone ); |
|
101 } |
|
102 FLOG(_L("[BTNOTIF]\t CBTInqUI::IssueRequestL() completed")); |
|
103 } |
|
104 |
|
105 // ---------------------------------------------------------- |
|
106 // CBTInqUI::RequestCompletedL |
|
107 // BT-device or timeout has been received. Inform caller for |
|
108 // received device and issue next EIR/Name request. |
|
109 // ---------------------------------------------------------- |
|
110 // |
|
111 void CBTInqUI::RequestCompletedL( CBTNotifActive* aActive, TInt aId, TInt aStatus ) |
|
112 { |
|
113 FTRACE(FPrint(_L("[BTNOTIF]\t CBTInqUI::RequestCompletedL() status: %d >>"), aStatus )); |
|
114 ASSERT( aId == KBTNotifInquiryNotifierReq); |
|
115 (void) aActive; |
|
116 |
|
117 TInt firstPartialNameDevIndex = -1; |
|
118 const TBool haveDevsWithPartialName = HaveDevsWithPartialName(firstPartialNameDevIndex); |
|
119 |
|
120 if( aStatus == KErrNone ) |
|
121 { |
|
122 if( iPageForName ) |
|
123 { |
|
124 FLOG(_L("[BTNOTIF]\t CBTInqUI::RequestCompletedL() in name request state.")); |
|
125 |
|
126 if (haveDevsWithPartialName) |
|
127 { |
|
128 // We resolve names in chronological order so it must be the first device |
|
129 // with an incomplete name we can find on the last seen list. |
|
130 HandleUpdatedNameL(firstPartialNameDevIndex); |
|
131 } |
|
132 else |
|
133 { |
|
134 // Must be the current index in iDevsWithoutName. |
|
135 HandleFoundNameL(); |
|
136 iCurrentlyResolvingUnnamedDeviceIndex++; |
|
137 } |
|
138 IssueRequestL(); |
|
139 } |
|
140 else |
|
141 { |
|
142 HandleInquiryDeviceL(); |
|
143 iHostResolver.Next( iEntry, iScanner->RequestStatus() ); |
|
144 iScanner->GoActive(); |
|
145 } |
|
146 } |
|
147 else if( aStatus == (KHCIErrorBase - EPageTimedOut) && iPageForName ) |
|
148 { |
|
149 FLOG(_L("[BTNOTIF]\t CBTInqUI::RequestCompletedL() HCI:EPageTimeOut, page next one.")); |
|
150 if (haveDevsWithPartialName) |
|
151 { |
|
152 // A device with incomplete name has probably gone out of range. Just removing |
|
153 // it from the UI may be a bit confusing, so let's just update its RSSI indicator |
|
154 // to minimum. |
|
155 PageTimeoutOnDeviceWithPartialNameL(firstPartialNameDevIndex); |
|
156 } |
|
157 else |
|
158 { |
|
159 iCurrentlyResolvingUnnamedDeviceIndex++; |
|
160 } |
|
161 IssueRequestL(); |
|
162 } |
|
163 else |
|
164 { |
|
165 if( !iPageForName && (iDevsWithoutName.Count() > 0 || haveDevsWithPartialName) ) |
|
166 { |
|
167 FTRACE(FPrint(_L("[BTNOTIF]\t CBTInqUI::RequestCompletedL() have devs with incomplete name = %d, nameless devices %d, paging for name."), |
|
168 haveDevsWithPartialName, iDevsWithoutName.Count() )); |
|
169 iCurrentlyResolvingUnnamedDeviceIndex = 0; |
|
170 iPageForName = ETrue; |
|
171 IssueRequestL(); |
|
172 } |
|
173 else |
|
174 { |
|
175 FLOG(_L("[BTNOTIF]\t CBTInqUI::RequestCompletedL() NameInquiryComplete with error or no device found.")); |
|
176 HandleError( aActive, aId, aStatus ); |
|
177 } |
|
178 } |
|
179 FLOG(_L("[BTNOTIF]\t CBTInqUI::RequestCompletedL() <<")); |
|
180 } |
|
181 |
|
182 // ---------------------------------------------------------- |
|
183 // CBTInqUI::HandleError |
|
184 // Inform UI from error occured. |
|
185 // ---------------------------------------------------------- |
|
186 // |
|
187 void CBTInqUI::HandleError( CBTNotifActive* aActive, TInt aId, TInt aError ) |
|
188 { |
|
189 FLOG(_L("[BTNOTIF]\t CBTInqUI::HandleError()")); |
|
190 (void) aActive; |
|
191 (void) aId; |
|
192 iPageForName = EFalse; |
|
193 InquiryComplete( aError ); |
|
194 FLOG(_L("[BTNOTIF]\t CBTInqUI::HandleError() completed")); |
|
195 } |
|
196 |
|
197 // ---------------------------------------------------------- |
|
198 // CBTInqUI::DoCancelRequest |
|
199 // ---------------------------------------------------------- |
|
200 // |
|
201 void CBTInqUI::DoCancelRequest( CBTNotifActive* aActive, TInt aId ) |
|
202 { |
|
203 (void) aActive; |
|
204 (void) aId; |
|
205 iHostResolver.Cancel(); |
|
206 } |
|
207 |
|
208 // ---------------------------------------------------------- |
|
209 // CBTInqUI::HandleInquiryDeviceL |
|
210 // Inform of properties of the found BTdevice, |
|
211 // which passes the search filter. Its name would be retrived |
|
212 // later if not contained by the first round of inquiry. |
|
213 // ---------------------------------------------------------- |
|
214 // |
|
215 void CBTInqUI::HandleInquiryDeviceL() |
|
216 { |
|
217 TInquirySockAddr& sa = TInquirySockAddr::Cast( iEntry().iAddr ); |
|
218 |
|
219 if ( iDesiredDeviceClass.DeviceClass() == 0 || sa.MajorClassOfDevice() == iDesiredDeviceClass.MajorDeviceClass() ) |
|
220 { |
|
221 FLOG(_L("[BTNOTIF]\t CBTInqUI::HandleInquiryDeviceL() The found device passes the search filter.")); |
|
222 #ifdef _DEBUG |
|
223 TBuf<12> devAddrString; |
|
224 sa.BTAddr().GetReadable(devAddrString); |
|
225 FTRACE(FPrint(_L("[BTNOTIF]\t BT Address: %S"), &devAddrString)); |
|
226 #endif |
|
227 TBTDeviceName devName; |
|
228 TBool isNameComplete(EFalse); |
|
229 TBool nameGotten = CheckEirDeviceName( iEntry, devName, isNameComplete ); |
|
230 FTRACE(FPrint(_L("[BTNOTIF]\t CBTInqUI::HandleInquiryDeviceL() EIR device name? %d, %S, complete = %d"), nameGotten, &devName, isNameComplete )); |
|
231 if( nameGotten ) |
|
232 { |
|
233 DeviceAvailableL( iEntry(), devName, isNameComplete ); |
|
234 } |
|
235 else |
|
236 { |
|
237 iDevsWithoutName.AppendL( iEntry() ); |
|
238 } |
|
239 } |
|
240 } |
|
241 |
|
242 // ---------------------------------------------------------- |
|
243 // CBTInqUI::HandleFoundNameL |
|
244 // Inform of retrieved device name after 2nd inquiry. |
|
245 // ---------------------------------------------------------- |
|
246 // |
|
247 void CBTInqUI::HandleFoundNameL() |
|
248 { |
|
249 #ifdef _DEBUG |
|
250 TBuf<12> devAddrString; |
|
251 TInquirySockAddr& sa = TInquirySockAddr::Cast( iEntry().iAddr ); |
|
252 sa.BTAddr().GetReadable(devAddrString); |
|
253 FTRACE(FPrint(_L("[BTNOTIF]\t CBTInqUI::HandleFoundNameL() BT Address: %S"), &devAddrString)); |
|
254 #endif |
|
255 if( iEntry().iName != KNullDesC ) |
|
256 { |
|
257 FTRACE(FPrint(_L("[BTNOTIF]\t CBTInqUI::HandleFoundNameL() Name found: %S"), &(iEntry().iName) )); |
|
258 DeviceAvailableL( iDevsWithoutName[iCurrentlyResolvingUnnamedDeviceIndex], iEntry().iName, ETrue ); |
|
259 } |
|
260 |
|
261 FLOG(_L("[BTNOTIF]\t CBTInqUI::HandleFoundNameL() Complete")); |
|
262 } |
|
263 |
|
264 void CBTInqUI::HandleUpdatedNameL(TInt aLastSeenIndex) |
|
265 { |
|
266 #ifdef _DEBUG |
|
267 TBuf<12> devAddrString; |
|
268 TInquirySockAddr& sa = TInquirySockAddr::Cast( iEntry().iAddr ); |
|
269 sa.BTAddr().GetReadable(devAddrString); |
|
270 FTRACE(FPrint(_L("[BTNOTIF]\t CBTInqUI::HandleUpdatedNameL() BT Address: %S"), &devAddrString)); |
|
271 #endif |
|
272 iLastSeenDevicesNameComplete[aLastSeenIndex] = ETrue; |
|
273 if( iEntry().iName != KNullDesC ) |
|
274 { |
|
275 DeviceNameUpdatedL(iEntry(), aLastSeenIndex); |
|
276 } |
|
277 |
|
278 FTRACE(FPrint(_L("[BTNOTIF]\t CBTInqUI::HandleUpdatedNameL() Complete"))); |
|
279 } |
|
280 |
|
281 |
|
282 // ---------------------------------------------------------- |
|
283 // CBTInqUI::CheckEirDeviceName |
|
284 // Check if the retrieved the device info contains device name. |
|
285 // ---------------------------------------------------------- |
|
286 // |
|
287 TBool CBTInqUI::CheckEirDeviceName( TNameEntry& aEntry, TBTDeviceName& aName, TBool& aIsComplete ) |
|
288 { |
|
289 TBluetoothNameRecordWrapper eir( aEntry() ); |
|
290 TInt length = eir.GetDeviceNameLength(); |
|
291 |
|
292 TInt err( KErrNone ); |
|
293 |
|
294 if( length > 0 ) |
|
295 { |
|
296 err = eir.GetDeviceName( aName, aIsComplete); |
|
297 return (!err); |
|
298 } |
|
299 return EFalse; |
|
300 } |
|
301 // End of File |