|
1 // Copyright (c) 2006-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 <es_sock.h> |
|
17 #include <utf.h> |
|
18 #include "pbapappheader.h" |
|
19 |
|
20 #include "btaccesshostlog.h" |
|
21 |
|
22 |
|
23 /*static*/ CPbapAppHeader* CPbapAppHeader::NewL() |
|
24 { |
|
25 LOG_STATIC_FUNC |
|
26 return new(ELeave) CPbapAppHeader; |
|
27 } |
|
28 |
|
29 |
|
30 CPbapAppHeader::CPbapAppHeader() |
|
31 { |
|
32 LOG_FUNC |
|
33 Reset(); |
|
34 } |
|
35 |
|
36 CPbapAppHeader::~CPbapAppHeader() |
|
37 { |
|
38 LOG_FUNC |
|
39 iSearchValue.Close(); |
|
40 } |
|
41 |
|
42 /** |
|
43 Set values to defaults defined in the PBAP specification |
|
44 */ |
|
45 void CPbapAppHeader::Reset() |
|
46 { |
|
47 LOG_FUNC |
|
48 |
|
49 iTagsPresent.Reset(); |
|
50 iMaxListCount = KMaxTUint16; |
|
51 iListStartOffset = 0; |
|
52 iAttributeMask = SymbianPBAP::KPbapAttributeAll; |
|
53 iVCardVersion = EPBAPVCard21; |
|
54 iOrder = SymbianPBAP::EIndexed; |
|
55 iSearchValue.Close(); |
|
56 iSearchAttribute = SymbianPBAP::EName; |
|
57 iOperation = EUnknownOperation; |
|
58 iIsAbsolutePathOp = EFalse; |
|
59 } |
|
60 |
|
61 /** |
|
62 Parse the application parameters header for the underlying "PBAP PDU" |
|
63 this PBAP "PDU" is composed of the TLVs in the App Params Header |
|
64 */ |
|
65 void CPbapAppHeader::ParseL(const TDesC8& aObexApplicationHeader) |
|
66 { |
|
67 LOG_FUNC |
|
68 if (aObexApplicationHeader!=KNullDesC8) |
|
69 { |
|
70 TUint8 parseIndex = 0; |
|
71 TUint8 appHeaderLength = aObexApplicationHeader.Length(); |
|
72 while (parseIndex < appHeaderLength) |
|
73 { |
|
74 // get 'tag' from the header |
|
75 TApplicationHeaderTagId tag = static_cast<TApplicationHeaderTagId>(aObexApplicationHeader[parseIndex]); |
|
76 |
|
77 // check weather 'length' is present, then get 'length' |
|
78 if(++parseIndex == appHeaderLength) |
|
79 { |
|
80 User::Leave(KErrArgument); |
|
81 } |
|
82 TUint8 length = static_cast<TUint8>(aObexApplicationHeader[parseIndex]); |
|
83 // check weather 'length' is longer than the remaining header |
|
84 if (appHeaderLength-parseIndex <= length) |
|
85 { |
|
86 User::Leave(KErrArgument); |
|
87 } |
|
88 |
|
89 TPtrC8 nextValue = aObexApplicationHeader.Mid(++parseIndex,length); |
|
90 |
|
91 if (nextValue.Length() != length) |
|
92 { |
|
93 User::Leave(KErrArgument); |
|
94 } |
|
95 |
|
96 switch (tag) |
|
97 { |
|
98 case EOrder: |
|
99 { |
|
100 LOG(_L("Order tag present")); |
|
101 // check whether the parameters header is valid |
|
102 if (length!=1) |
|
103 { |
|
104 User::Leave(KErrArgument); |
|
105 } |
|
106 iOrder = ConvertToOrder(nextValue[0]); |
|
107 LOG1(_L("Order = %d"), iOrder); |
|
108 if (iOrder == SymbianPBAP::EUnknownOrder) |
|
109 { |
|
110 User::Leave(KErrArgument); |
|
111 } |
|
112 } |
|
113 break; |
|
114 case ESearchValue: |
|
115 { |
|
116 LOG(_L("SearchValue tag present")); |
|
117 |
|
118 // the search string may have a null terminator, if so remove it |
|
119 TPtrC8 searchValue(nextValue); |
|
120 if (length && searchValue[length-1]=='\0') |
|
121 { |
|
122 LOG(_L("Removing null terminator from search value")); |
|
123 searchValue.Set(searchValue.Left(length-1)); |
|
124 } |
|
125 |
|
126 // convert the search string from UTF-8 to unicode |
|
127 iSearchValue.Assign(CnvUtfConverter::ConvertToUnicodeFromUtf8L(searchValue)); // ownership transferred |
|
128 LOG1(_L("SearchValue = %S"), &iSearchValue); |
|
129 } |
|
130 break; |
|
131 case ESearchAttribute: |
|
132 { |
|
133 LOG(_L("SearchAttribute tag present")); |
|
134 if (length!=1) |
|
135 { |
|
136 User::Leave(KErrArgument); |
|
137 } |
|
138 iSearchAttribute = ConvertToSearchAttribute(nextValue[0]); |
|
139 LOG1(_L("SearchAttribute = %d"), iSearchAttribute); |
|
140 if (iSearchAttribute == SymbianPBAP::EUnknownSearchAttribute) |
|
141 { |
|
142 User::Leave(KErrArgument); |
|
143 } |
|
144 } |
|
145 break; |
|
146 case EMaxListCount: |
|
147 { |
|
148 LOG(_L("MaxListCount tag present")); |
|
149 if (length!=2) |
|
150 { |
|
151 User::Leave(KErrArgument); |
|
152 } |
|
153 iMaxListCount = BigEndian::Get16(nextValue.Ptr()); |
|
154 LOG1(_L("MaxListCount=%d"), iMaxListCount); |
|
155 } |
|
156 break; |
|
157 case EListStartOffset: |
|
158 { |
|
159 LOG(_L("ListStartOffset tag present")); |
|
160 if (length!=2) |
|
161 { |
|
162 User::Leave(KErrArgument); |
|
163 } |
|
164 iListStartOffset = BigEndian::Get16(nextValue.Ptr()); |
|
165 LOG1(_L("ListStartOffset = %d"), iListStartOffset); |
|
166 } |
|
167 break; |
|
168 case EFilter: |
|
169 { |
|
170 LOG(_L("Filter tag present")); |
|
171 if (length!=8) |
|
172 { |
|
173 User::Leave(KErrArgument); |
|
174 } |
|
175 iAttributeMask = ConvertToFilter(nextValue.Ptr()); |
|
176 LOG1(_L("Filter tag = %d"), iAttributeMask); |
|
177 } |
|
178 break; |
|
179 case EFormat: |
|
180 { |
|
181 LOG(_L("Format tag present")); |
|
182 if (length!=1) |
|
183 { |
|
184 User::Leave(KErrArgument); |
|
185 } |
|
186 iVCardVersion = ConvertToVCardVersionL(nextValue[0]); |
|
187 LOG1(_L("vCard version = %d"), iVCardVersion); |
|
188 } |
|
189 break; |
|
190 default: |
|
191 // ignore unknown tag |
|
192 break; |
|
193 } |
|
194 |
|
195 // completely ignore any unspecified tags |
|
196 if (tag < EBeginningOfUnspecifiedTags && tag > 0) |
|
197 { |
|
198 iTagsPresent[tag] = ETrue; |
|
199 } |
|
200 |
|
201 parseIndex+=length; |
|
202 } |
|
203 } |
|
204 } |
|
205 |
|
206 /** |
|
207 convert sort order parameter values defined in PBAP specification to internal enum |
|
208 */ |
|
209 SymbianPBAP::TOrder CPbapAppHeader::ConvertToOrder(TUint8 aValue) const |
|
210 { |
|
211 LOG_FUNC |
|
212 SymbianPBAP::TOrder order; |
|
213 switch (aValue) |
|
214 { |
|
215 case 0x00: |
|
216 order = SymbianPBAP::EIndexed; |
|
217 break; |
|
218 case 0x01: |
|
219 order = SymbianPBAP::EAlphabetical; |
|
220 break; |
|
221 case 0x02: |
|
222 order = SymbianPBAP::EPhonetical; |
|
223 break; |
|
224 default: |
|
225 order = SymbianPBAP::EUnknownOrder; |
|
226 break; |
|
227 } |
|
228 return order; |
|
229 } |
|
230 |
|
231 |
|
232 /** |
|
233 convert search attribute parameter values defined in PBAP specification to internal enum |
|
234 */ |
|
235 SymbianPBAP::TSearchAttribute CPbapAppHeader::ConvertToSearchAttribute(TUint8 aValue) const |
|
236 { |
|
237 LOG_FUNC |
|
238 SymbianPBAP::TSearchAttribute searchAttrib; |
|
239 switch (aValue) |
|
240 { |
|
241 case 0x00: |
|
242 searchAttrib = SymbianPBAP::EName; |
|
243 break; |
|
244 case 0x01: |
|
245 searchAttrib = SymbianPBAP::ENumber; |
|
246 break; |
|
247 case 0x02: |
|
248 searchAttrib = SymbianPBAP::ESound; |
|
249 break; |
|
250 default: |
|
251 searchAttrib = SymbianPBAP::EUnknownSearchAttribute; |
|
252 break; |
|
253 } |
|
254 return searchAttrib; |
|
255 } |
|
256 |
|
257 /** |
|
258 convert format parameter values defined in PBAP specification to internal enum |
|
259 */ |
|
260 TVCardVersion CPbapAppHeader::ConvertToVCardVersionL(TUint8 aValue) const |
|
261 { |
|
262 LOG_FUNC |
|
263 TVCardVersion version = EPBAPVCard21; |
|
264 switch (aValue) |
|
265 { |
|
266 case 0x00: |
|
267 version = EPBAPVCard21; |
|
268 break; |
|
269 case 0x01: |
|
270 version = EPBAPVCard30; |
|
271 break; |
|
272 default: |
|
273 User::Leave(KErrArgument); |
|
274 break; |
|
275 } |
|
276 return version; |
|
277 } |
|
278 |
|
279 /** |
|
280 Converts big-endian formatted descriptor to 64-bit filter mask |
|
281 */ |
|
282 TUint64 CPbapAppHeader::ConvertToFilter(const TUint8* aPtr) const |
|
283 { |
|
284 LOG_FUNC |
|
285 return ((static_cast<TUint64>(aPtr[0])<<56) | |
|
286 (static_cast<TUint64>(aPtr[1])<<48) | |
|
287 (static_cast<TUint64>(aPtr[2])<<40) | |
|
288 (static_cast<TUint64>(aPtr[3])<<32) | |
|
289 (static_cast<TUint64>(aPtr[4])<<24) | |
|
290 (static_cast<TUint64>(aPtr[5])<<16) | |
|
291 (static_cast<TUint64>(aPtr[6])<<8) | |
|
292 (static_cast<TUint64>(aPtr[7]))); |
|
293 } |
|
294 |
|
295 /** |
|
296 Determine the actual PBAP operation from the type header and the parsed |
|
297 application parameter header |
|
298 */ |
|
299 TPbapOperation CPbapAppHeader::DeterminePBAPOperationL(const TDesC8& aTypeHeader) |
|
300 { |
|
301 LOG_FUNC |
|
302 |
|
303 #ifdef __FLOG_ACTIVE |
|
304 RBuf buf; |
|
305 buf.CreateL(aTypeHeader.Length()); |
|
306 buf.Copy(aTypeHeader); |
|
307 LOG1(_L("Type header: %S"), &buf); |
|
308 buf.Close(); |
|
309 #endif |
|
310 |
|
311 TPtrC8 typeHeader(aTypeHeader); |
|
312 TInt length = aTypeHeader.Length(); |
|
313 |
|
314 // obex may append null terminator to type header, if so remove it |
|
315 if (length && aTypeHeader[length-1]=='\0') |
|
316 { |
|
317 typeHeader.Set(aTypeHeader.Left(length-1)); |
|
318 } |
|
319 |
|
320 if (typeHeader.CompareF(KObexTypeBTvCardPhoneBook)==0) |
|
321 { |
|
322 if (!iTagsPresent[EMaxListCount]) |
|
323 { |
|
324 LOG(_L("Missing mandatory MaxListCount tag in App Header")); |
|
325 // mandatory to have the tag present in this operation |
|
326 User::Leave(KErrArgument); |
|
327 } |
|
328 if (iMaxListCount==0) |
|
329 { |
|
330 iOperation = ERequestPhoneBookSize; |
|
331 LOG(_L("PBAP operation is PullPhoneBook - MaxListCount = 0")); |
|
332 } |
|
333 else |
|
334 { |
|
335 iOperation = EPullPhoneBook; |
|
336 LOG(_L("PBAP operation is PullPhoneBook")); |
|
337 } |
|
338 |
|
339 // this type of request operates on absolute paths |
|
340 iIsAbsolutePathOp = ETrue; |
|
341 } |
|
342 else if (typeHeader.CompareF(KObexTypeBTvCardListing)==0) |
|
343 { |
|
344 if (!iTagsPresent[EMaxListCount]) |
|
345 { |
|
346 LOG(_L("Missing MaxListCount tag in App Header, continuing due to spec (v1.0) inconsistency")); |
|
347 } |
|
348 if (iMaxListCount==0) |
|
349 { |
|
350 iOperation = ERequestPhoneBookSize; |
|
351 LOG(_L("PBAP operation is PullvCardListing - MaxListCount = 0")); |
|
352 } |
|
353 else |
|
354 { |
|
355 iOperation = EPullVCardListing; |
|
356 LOG(_L("PBAP operation is PullvCardListing")); |
|
357 } |
|
358 } |
|
359 else if (typeHeader.CompareF(KObexTypeBTvCard)==0) |
|
360 { |
|
361 // leave to folderparser to determine if handle is ok |
|
362 iOperation = EPullVCard; |
|
363 LOG(_L("PBAP operation is PullvCard")); |
|
364 } |
|
365 else |
|
366 { |
|
367 // incorrect or nonexistent Type header. Bad. |
|
368 LOG(_L("Cannot determine PBAP operation")); |
|
369 User::Leave(KErrCorrupt); |
|
370 } |
|
371 |
|
372 return iOperation; |
|
373 } |