|
1 // Copyright (c) 2007-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 "tavsrcUtils.h" |
|
17 #include "tavsrcConsole.h" |
|
18 |
|
19 #include <bluetoothav.h> |
|
20 #include <btextnotifiers.h> |
|
21 |
|
22 #include <f32file.h> |
|
23 #include <e32math.h> |
|
24 |
|
25 void TTavsrcUtils::RegisterSinkSDPRecordL(RSdpDatabase& aDB, TSdpServRecordHandle& aRecHandle, |
|
26 TBool aHeadphone, TBool aSpeaker, TBool aRecorder, |
|
27 TBool aAmp) |
|
28 { |
|
29 CSdpAttrValue* attrVal = 0; |
|
30 CSdpAttrValueDES* attrValDES = 0; |
|
31 |
|
32 // Set Attr 1 (service class list) to list with UUID = Audio Sink |
|
33 aDB.CreateServiceRecordL(TUUID(KAudioSinkUUID), aRecHandle); |
|
34 |
|
35 // Protocol Descriptor List |
|
36 attrValDES = CSdpAttrValueDES::NewDESL(0); |
|
37 CleanupStack::PushL(attrValDES); |
|
38 |
|
39 attrValDES->StartListL() |
|
40 ->BuildDESL() |
|
41 ->StartListL() |
|
42 ->BuildUUIDL(TUUID(TUint16(KL2CAPUUID))) // L2CAP |
|
43 ->BuildUintL(TSdpIntBuf<TUint16>(KAVDTP)) // PSM = AVDTP |
|
44 ->EndListL() |
|
45 ->BuildDESL() |
|
46 ->StartListL() |
|
47 ->BuildUUIDL(TUUID(TUint16(KAvdtpUUID))) // Avdtp UUID |
|
48 ->BuildUintL(TSdpIntBuf<TUint16>(0x0100)) // Version |
|
49 ->EndListL() |
|
50 ->EndListL(); |
|
51 aDB.UpdateAttributeL(aRecHandle, KSdpAttrIdProtocolDescriptorList, *attrValDES); |
|
52 CleanupStack::PopAndDestroy(attrValDES); |
|
53 attrValDES = 0; |
|
54 |
|
55 //BrowseGroupList |
|
56 /* |
|
57 This has been added in order to be interoperable with remote devices which only look for the |
|
58 service in the PublicBrowseGroup (the root of the browse hierarchy). This is not a mandatory feature. |
|
59 */ |
|
60 attrValDES = CSdpAttrValueDES::NewDESL(0); |
|
61 CleanupStack::PushL(attrValDES); |
|
62 |
|
63 attrValDES->StartListL() |
|
64 ->BuildUUIDL(TUUID(TUint16(KPublicBrowseGroupUUID))) // Public browse group (the root) |
|
65 ->EndListL(); |
|
66 aDB.UpdateAttributeL(aRecHandle, KSdpAttrIdBrowseGroupList, *attrValDES); //attribute 5 |
|
67 CleanupStack::PopAndDestroy(attrValDES); |
|
68 attrValDES = NULL; |
|
69 |
|
70 // Language |
|
71 attrValDES = CSdpAttrValueDES::NewDESL(0); |
|
72 CleanupStack::PushL(attrValDES); |
|
73 |
|
74 attrValDES->StartListL() |
|
75 ->BuildUintL(TSdpIntBuf<TUint16>(KLanguageEnglish)) |
|
76 ->BuildUintL(TSdpIntBuf<TUint16>(KSdpAttrIdCharacterEncodingUTF8)) |
|
77 ->BuildUintL(TSdpIntBuf<TUint16>(KSdpAttrIdBasePrimaryLanguage)) |
|
78 ->EndListL(); |
|
79 aDB.UpdateAttributeL(aRecHandle, KSdpAttrIdLanguageBaseAttributeIDList, *attrValDES); |
|
80 CleanupStack::PopAndDestroy(attrValDES); |
|
81 attrValDES = 0; |
|
82 |
|
83 // BT Profile Description |
|
84 attrValDES = CSdpAttrValueDES::NewDESL(0); |
|
85 CleanupStack::PushL(attrValDES); |
|
86 |
|
87 attrValDES->StartListL() |
|
88 ->BuildDESL()->StartListL() |
|
89 ->BuildUUIDL(KAdvancedAudioDistributionUUID) |
|
90 ->BuildUintL(TSdpIntBuf<TUint16>(0x0100)) // version |
|
91 ->EndListL() |
|
92 ->EndListL(); |
|
93 aDB.UpdateAttributeL(aRecHandle, KSdpAttrIdBluetoothProfileDescriptorList, *attrValDES); |
|
94 |
|
95 CleanupStack::PopAndDestroy(attrValDES); |
|
96 attrValDES = 0; |
|
97 |
|
98 // provider name |
|
99 attrVal = CSdpAttrValueString::NewStringL(_L8("Symbian Software Ltd")); |
|
100 CleanupStack::PushL(attrVal); |
|
101 aDB.UpdateAttributeL(aRecHandle, KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetProviderName, *attrVal); |
|
102 CleanupStack::PopAndDestroy(attrVal); |
|
103 attrVal = 0; |
|
104 |
|
105 // service name |
|
106 attrVal = CSdpAttrValueString::NewStringL(_L8("Advanced audio distribution sink")); |
|
107 CleanupStack::PushL(attrVal); |
|
108 aDB.UpdateAttributeL(aRecHandle, KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceName, *attrVal); |
|
109 CleanupStack::PopAndDestroy(attrVal); |
|
110 attrVal = 0; |
|
111 |
|
112 // service description |
|
113 attrVal = CSdpAttrValueString::NewStringL(_L8("kick back and listen to some fine tunes with this neat service")); |
|
114 CleanupStack::PushL(attrVal); |
|
115 aDB.UpdateAttributeL(aRecHandle, KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceDescription, *attrVal); |
|
116 CleanupStack::PopAndDestroy(attrVal); |
|
117 attrVal = 0; |
|
118 |
|
119 // supported features |
|
120 TUint16 supportedFeatures = aHeadphone ? 1:0; |
|
121 supportedFeatures|=aSpeaker ? 2:0; |
|
122 supportedFeatures|=aRecorder ? 4:0; |
|
123 supportedFeatures|=aAmp ? 8:0; |
|
124 attrVal = CSdpAttrValueUint::NewUintL(TSdpIntBuf<TUint16>(supportedFeatures)); |
|
125 CleanupStack::PushL(attrVal); |
|
126 |
|
127 aDB.UpdateAttributeL(aRecHandle, KSdpAttrIdSupportedFeatures, *attrVal); |
|
128 CleanupStack::PopAndDestroy(attrVal); |
|
129 attrVal = 0; |
|
130 } |
|
131 |
|
132 void TTavsrcUtils::RegisterSourceSDPRecordL(RSdpDatabase& aDB, TSdpServRecordHandle& aRecHandle, |
|
133 TBool aPlayer, TBool aMic, TBool aTuner, TBool aMixer) |
|
134 { |
|
135 CSdpAttrValue* attrVal = 0; |
|
136 CSdpAttrValueDES* attrValDES = 0; |
|
137 |
|
138 // Set Attr 1 (service class list) to list with UUID = Audio Sink |
|
139 aDB.CreateServiceRecordL(TUUID(KAudioSourceUUID), aRecHandle); |
|
140 |
|
141 // Protocol Descriptor List |
|
142 attrValDES = CSdpAttrValueDES::NewDESL(0); |
|
143 CleanupStack::PushL(attrValDES); |
|
144 |
|
145 attrValDES->StartListL() |
|
146 ->BuildDESL() |
|
147 ->StartListL() |
|
148 ->BuildUUIDL(TUUID(TUint16(KL2CAPUUID))) // L2CAP |
|
149 ->BuildUintL(TSdpIntBuf<TUint16>(KAVDTP)) // PSM = AVDTP |
|
150 ->EndListL() |
|
151 ->BuildDESL() |
|
152 ->StartListL() |
|
153 ->BuildUUIDL(TUUID(TUint16(KAvdtpUUID))) // Avdtp UUID |
|
154 ->BuildUintL(TSdpIntBuf<TUint16>(0x0100)) // Version |
|
155 ->EndListL() |
|
156 ->EndListL(); |
|
157 aDB.UpdateAttributeL(aRecHandle, KSdpAttrIdProtocolDescriptorList, *attrValDES); |
|
158 CleanupStack::PopAndDestroy(attrValDES); |
|
159 attrValDES = 0; |
|
160 |
|
161 //BrowseGroupList |
|
162 /* |
|
163 This has been added in order to be interoperable with remote devices which only look for the |
|
164 service in the PublicBrowseGroup (the root of the browse hierarchy). This is not a mandatory feature. |
|
165 */ |
|
166 attrValDES = CSdpAttrValueDES::NewDESL(0); |
|
167 CleanupStack::PushL(attrValDES); |
|
168 |
|
169 attrValDES->StartListL() |
|
170 ->BuildUUIDL(TUUID(TUint16(KPublicBrowseGroupUUID))) // Public browse group (the root) |
|
171 ->EndListL(); |
|
172 aDB.UpdateAttributeL(aRecHandle, KSdpAttrIdBrowseGroupList, *attrValDES); //attribute 5 |
|
173 CleanupStack::PopAndDestroy(attrValDES); |
|
174 attrValDES = NULL; |
|
175 |
|
176 // Language |
|
177 attrValDES = CSdpAttrValueDES::NewDESL(0); |
|
178 CleanupStack::PushL(attrValDES); |
|
179 |
|
180 attrValDES->StartListL() |
|
181 ->BuildUintL(TSdpIntBuf<TUint16>(KLanguageEnglish)) |
|
182 ->BuildUintL(TSdpIntBuf<TUint16>(KSdpAttrIdCharacterEncodingUTF8)) |
|
183 ->BuildUintL(TSdpIntBuf<TUint16>(KSdpAttrIdBasePrimaryLanguage)) |
|
184 ->EndListL(); |
|
185 aDB.UpdateAttributeL(aRecHandle, KSdpAttrIdLanguageBaseAttributeIDList, *attrValDES); |
|
186 CleanupStack::PopAndDestroy(attrValDES); |
|
187 attrValDES = 0; |
|
188 |
|
189 // BT Profile Description |
|
190 attrValDES = CSdpAttrValueDES::NewDESL(0); |
|
191 CleanupStack::PushL(attrValDES); |
|
192 |
|
193 attrValDES->StartListL() |
|
194 ->BuildDESL()->StartListL() |
|
195 ->BuildUUIDL(KAdvancedAudioDistributionUUID) |
|
196 ->BuildUintL(TSdpIntBuf<TUint16>(0x0100)) // version |
|
197 ->EndListL() |
|
198 ->EndListL(); |
|
199 aDB.UpdateAttributeL(aRecHandle, KSdpAttrIdBluetoothProfileDescriptorList, *attrValDES); |
|
200 |
|
201 CleanupStack::PopAndDestroy(attrValDES); |
|
202 attrValDES = 0; |
|
203 |
|
204 // provider name |
|
205 attrVal = CSdpAttrValueString::NewStringL(_L8("Symbian Software Ltd")); |
|
206 CleanupStack::PushL(attrVal); |
|
207 aDB.UpdateAttributeL(aRecHandle, KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetProviderName, *attrVal); |
|
208 CleanupStack::PopAndDestroy(attrVal); |
|
209 attrVal = 0; |
|
210 |
|
211 // service name |
|
212 attrVal = CSdpAttrValueString::NewStringL(_L8("Advanced audio distribution source")); |
|
213 CleanupStack::PushL(attrVal); |
|
214 aDB.UpdateAttributeL(aRecHandle, KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceName, *attrVal); |
|
215 CleanupStack::PopAndDestroy(attrVal); |
|
216 attrVal = 0; |
|
217 |
|
218 // service description |
|
219 attrVal = CSdpAttrValueString::NewStringL(_L8("plug your wireless cans into me!")); |
|
220 CleanupStack::PushL(attrVal); |
|
221 aDB.UpdateAttributeL(aRecHandle, KSdpAttrIdBasePrimaryLanguage + KSdpAttrIdOffsetServiceDescription, *attrVal); |
|
222 CleanupStack::PopAndDestroy(attrVal); |
|
223 attrVal = 0; |
|
224 |
|
225 // supported features |
|
226 TUint16 supportedFeatures = aPlayer ? 1:0; |
|
227 supportedFeatures|=aMic ? 2:0; |
|
228 supportedFeatures|=aTuner ? 4:0; |
|
229 supportedFeatures|=aMixer ? 8:0; |
|
230 attrVal = CSdpAttrValueUint::NewUintL(TSdpIntBuf<TUint16>(supportedFeatures)); |
|
231 CleanupStack::PushL(attrVal); |
|
232 |
|
233 aDB.UpdateAttributeL(aRecHandle, KSdpAttrIdSupportedFeatures, *attrVal); |
|
234 CleanupStack::PopAndDestroy(attrVal); |
|
235 attrVal = 0; |
|
236 } |
|
237 |
|
238 TInt TTavsrcUtils::GetIntFromUser(CConsoleBase& aConsole) |
|
239 { |
|
240 TBuf<4> inpb; |
|
241 aConsole.Printf(_L(":")); |
|
242 TInt x = aConsole.WhereX(); |
|
243 TInt y = aConsole.WhereY(); |
|
244 TRequestStatus stat; |
|
245 |
|
246 TChar ch(0); // set it to anything to prevent warning |
|
247 while ((ch!='\n')&&(ch!='\r') && inpb.Length()==0) |
|
248 { |
|
249 aConsole.Read(stat); |
|
250 User::WaitForRequest(stat); |
|
251 ch = aConsole.KeyCode(); |
|
252 |
|
253 if ((ch=='\b') && (inpb.Length()>0)) |
|
254 { |
|
255 inpb.Delete(inpb.Length()-1,1); |
|
256 } |
|
257 |
|
258 if ((inpb.Length()<4)&&((ch>='0')&&(ch<='9'))) |
|
259 { |
|
260 inpb.Append(ch); |
|
261 } |
|
262 |
|
263 aConsole.SetPos(x,y); |
|
264 aConsole.Printf(_L("%S"),&inpb); |
|
265 } |
|
266 |
|
267 TLex lex(inpb); |
|
268 TInt res; |
|
269 return (lex.Val(res)==KErrNone) ? res : 0; |
|
270 } |
|
271 |
|
272 TBool TTavsrcUtils::GetYNFromUser(CConsoleBase& aConsole, const TDesC& aDes) |
|
273 { |
|
274 TBuf<4> inpb; |
|
275 aConsole.Printf(_L("%S (y/n):"),&aDes); |
|
276 TRequestStatus stat; |
|
277 |
|
278 TChar ch(0); // set it to anything to prevent warning |
|
279 while ((ch!='n')&&(ch!='y')) |
|
280 { |
|
281 aConsole.Read(stat); |
|
282 User::WaitForRequest(stat); |
|
283 ch = aConsole.KeyCode(); |
|
284 } |
|
285 aConsole.Printf(_L("%c"), static_cast<TUint>(ch)); |
|
286 return (ch=='y') ? ETrue : EFalse; |
|
287 } |
|
288 |
|
289 void TTavsrcUtils::GetDeviceAddressL(TBTDevAddr& aAddr) |
|
290 { |
|
291 //Ask user which device address we should connect to... |
|
292 RNotifier notify; |
|
293 User::LeaveIfError(notify.Connect()); |
|
294 TBTDeviceSelectionParamsPckg pckg; |
|
295 TBTDeviceResponseParamsPckg resPckg; |
|
296 TRequestStatus stat; |
|
297 notify.StartNotifierAndGetResponse(stat, KDeviceSelectionNotifierUid, pckg, resPckg); |
|
298 User::WaitForRequest(stat); |
|
299 notify.CancelNotifier(KDeviceSelectionNotifierUid); |
|
300 notify.Close(); |
|
301 User::LeaveIfError(stat.Int()); |
|
302 |
|
303 aAddr = resPckg().BDAddr(); |
|
304 } |
|
305 |
|
306 TInt TTavsrcUtils::GetCodecSettingsFromSBCFile(RFile& aFile, TInt aPos, TInt& aChannelMode, |
|
307 TInt& aNumChannels, TInt& aNumSubbands, TInt& aBlkLen, |
|
308 TInt& aBitPool, TInt& aFreq, TInt& aAllocMethod) |
|
309 { |
|
310 TInt err = KErrNone; |
|
311 |
|
312 TBuf8<4> header; |
|
313 aFile.Read(aPos, header); |
|
314 TInt syncWord = header[0]; |
|
315 __ASSERT_ALWAYS(syncWord==0x9C, User::Invariant()); |
|
316 |
|
317 TInt sampleFreq = (header[1]&0xC0)>>6; |
|
318 TInt blockLen = (header[1]&0x30)>>4; |
|
319 aChannelMode = (header[1]&0x0C)>>2; |
|
320 aAllocMethod = (header[1]&0x02)>>1; |
|
321 TInt subBands = (header[1]&0x01); |
|
322 aBitPool = header[2]; |
|
323 |
|
324 aNumChannels = (aChannelMode==0) ? 1 : 2; |
|
325 aNumSubbands = (subBands==1) ? 8 : 4; |
|
326 |
|
327 switch (sampleFreq) |
|
328 { |
|
329 case 0x00: |
|
330 aFreq = 16000; |
|
331 break; |
|
332 case 0x01: |
|
333 aFreq = 32000; |
|
334 break; |
|
335 case 0x02: |
|
336 aFreq = 44100; |
|
337 break; |
|
338 case 0x03: |
|
339 aFreq = 48000; |
|
340 break; |
|
341 } |
|
342 |
|
343 switch (blockLen) |
|
344 { |
|
345 case 0x00: |
|
346 aBlkLen = 4; |
|
347 break; |
|
348 case 0x01: |
|
349 aBlkLen = 8; |
|
350 break; |
|
351 case 0x02: |
|
352 aBlkLen = 12; |
|
353 break; |
|
354 case 0x03: |
|
355 aBlkLen = 16; |
|
356 break; |
|
357 } |
|
358 |
|
359 return err; |
|
360 } |
|
361 |
|
362 TInt TTavsrcUtils::GetCodecSettingsFromSBCFile(const TDesC& aFileName, TInt& aChannelMode, |
|
363 TInt& aNumChannels, TInt& aNumSubbands, TInt& aBlkLen, |
|
364 TInt& aBitPool, TInt& aFreq, TInt& aAllocMethod) |
|
365 { |
|
366 TInt err = KErrNone; |
|
367 |
|
368 RFs fileserver; |
|
369 RFile file; |
|
370 |
|
371 err = fileserver.Connect(); |
|
372 if (!err) |
|
373 { |
|
374 err = file.Open(fileserver,aFileName,EFileRead | EFileShareReadersOnly); |
|
375 } |
|
376 if (err) |
|
377 { |
|
378 return err; |
|
379 } |
|
380 |
|
381 err = GetCodecSettingsFromSBCFile(file, 0, aChannelMode, aNumChannels, aNumSubbands, |
|
382 aBlkLen, aBitPool, aFreq, aAllocMethod); |
|
383 file.Close(); |
|
384 fileserver.Close(); |
|
385 |
|
386 return err; |
|
387 } |
|
388 |
|
389 TInt TTavsrcUtils::CEIL(TReal aX) |
|
390 { |
|
391 TReal frac; |
|
392 Math::Frac(frac,aX); |
|
393 return (frac < 0.5) ? aX :aX+1; |
|
394 } |