--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pimprotocols/pbap/server/pbapappheader.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,373 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <es_sock.h>
+#include <utf.h>
+#include "pbapappheader.h"
+
+#include "btaccesshostlog.h"
+
+
+/*static*/ CPbapAppHeader* CPbapAppHeader::NewL()
+ {
+ LOG_STATIC_FUNC
+ return new(ELeave) CPbapAppHeader;
+ }
+
+
+CPbapAppHeader::CPbapAppHeader()
+ {
+ LOG_FUNC
+ Reset();
+ }
+
+CPbapAppHeader::~CPbapAppHeader()
+ {
+ LOG_FUNC
+ iSearchValue.Close();
+ }
+
+/**
+Set values to defaults defined in the PBAP specification
+*/
+void CPbapAppHeader::Reset()
+ {
+ LOG_FUNC
+
+ iTagsPresent.Reset();
+ iMaxListCount = KMaxTUint16;
+ iListStartOffset = 0;
+ iAttributeMask = SymbianPBAP::KPbapAttributeAll;
+ iVCardVersion = EPBAPVCard21;
+ iOrder = SymbianPBAP::EIndexed;
+ iSearchValue.Close();
+ iSearchAttribute = SymbianPBAP::EName;
+ iOperation = EUnknownOperation;
+ iIsAbsolutePathOp = EFalse;
+ }
+
+/**
+Parse the application parameters header for the underlying "PBAP PDU"
+this PBAP "PDU" is composed of the TLVs in the App Params Header
+*/
+void CPbapAppHeader::ParseL(const TDesC8& aObexApplicationHeader)
+ {
+ LOG_FUNC
+ if (aObexApplicationHeader!=KNullDesC8)
+ {
+ TUint8 parseIndex = 0;
+ TUint8 appHeaderLength = aObexApplicationHeader.Length();
+ while (parseIndex < appHeaderLength)
+ {
+ // get 'tag' from the header
+ TApplicationHeaderTagId tag = static_cast<TApplicationHeaderTagId>(aObexApplicationHeader[parseIndex]);
+
+ // check weather 'length' is present, then get 'length'
+ if(++parseIndex == appHeaderLength)
+ {
+ User::Leave(KErrArgument);
+ }
+ TUint8 length = static_cast<TUint8>(aObexApplicationHeader[parseIndex]);
+ // check weather 'length' is longer than the remaining header
+ if (appHeaderLength-parseIndex <= length)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 nextValue = aObexApplicationHeader.Mid(++parseIndex,length);
+
+ if (nextValue.Length() != length)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ switch (tag)
+ {
+ case EOrder:
+ {
+ LOG(_L("Order tag present"));
+ // check whether the parameters header is valid
+ if (length!=1)
+ {
+ User::Leave(KErrArgument);
+ }
+ iOrder = ConvertToOrder(nextValue[0]);
+ LOG1(_L("Order = %d"), iOrder);
+ if (iOrder == SymbianPBAP::EUnknownOrder)
+ {
+ User::Leave(KErrArgument);
+ }
+ }
+ break;
+ case ESearchValue:
+ {
+ LOG(_L("SearchValue tag present"));
+
+ // the search string may have a null terminator, if so remove it
+ TPtrC8 searchValue(nextValue);
+ if (length && searchValue[length-1]=='\0')
+ {
+ LOG(_L("Removing null terminator from search value"));
+ searchValue.Set(searchValue.Left(length-1));
+ }
+
+ // convert the search string from UTF-8 to unicode
+ iSearchValue.Assign(CnvUtfConverter::ConvertToUnicodeFromUtf8L(searchValue)); // ownership transferred
+ LOG1(_L("SearchValue = %S"), &iSearchValue);
+ }
+ break;
+ case ESearchAttribute:
+ {
+ LOG(_L("SearchAttribute tag present"));
+ if (length!=1)
+ {
+ User::Leave(KErrArgument);
+ }
+ iSearchAttribute = ConvertToSearchAttribute(nextValue[0]);
+ LOG1(_L("SearchAttribute = %d"), iSearchAttribute);
+ if (iSearchAttribute == SymbianPBAP::EUnknownSearchAttribute)
+ {
+ User::Leave(KErrArgument);
+ }
+ }
+ break;
+ case EMaxListCount:
+ {
+ LOG(_L("MaxListCount tag present"));
+ if (length!=2)
+ {
+ User::Leave(KErrArgument);
+ }
+ iMaxListCount = BigEndian::Get16(nextValue.Ptr());
+ LOG1(_L("MaxListCount=%d"), iMaxListCount);
+ }
+ break;
+ case EListStartOffset:
+ {
+ LOG(_L("ListStartOffset tag present"));
+ if (length!=2)
+ {
+ User::Leave(KErrArgument);
+ }
+ iListStartOffset = BigEndian::Get16(nextValue.Ptr());
+ LOG1(_L("ListStartOffset = %d"), iListStartOffset);
+ }
+ break;
+ case EFilter:
+ {
+ LOG(_L("Filter tag present"));
+ if (length!=8)
+ {
+ User::Leave(KErrArgument);
+ }
+ iAttributeMask = ConvertToFilter(nextValue.Ptr());
+ LOG1(_L("Filter tag = %d"), iAttributeMask);
+ }
+ break;
+ case EFormat:
+ {
+ LOG(_L("Format tag present"));
+ if (length!=1)
+ {
+ User::Leave(KErrArgument);
+ }
+ iVCardVersion = ConvertToVCardVersionL(nextValue[0]);
+ LOG1(_L("vCard version = %d"), iVCardVersion);
+ }
+ break;
+ default:
+ // ignore unknown tag
+ break;
+ }
+
+ // completely ignore any unspecified tags
+ if (tag < EBeginningOfUnspecifiedTags && tag > 0)
+ {
+ iTagsPresent[tag] = ETrue;
+ }
+
+ parseIndex+=length;
+ }
+ }
+ }
+
+/**
+ convert sort order parameter values defined in PBAP specification to internal enum
+*/
+SymbianPBAP::TOrder CPbapAppHeader::ConvertToOrder(TUint8 aValue) const
+ {
+ LOG_FUNC
+ SymbianPBAP::TOrder order;
+ switch (aValue)
+ {
+ case 0x00:
+ order = SymbianPBAP::EIndexed;
+ break;
+ case 0x01:
+ order = SymbianPBAP::EAlphabetical;
+ break;
+ case 0x02:
+ order = SymbianPBAP::EPhonetical;
+ break;
+ default:
+ order = SymbianPBAP::EUnknownOrder;
+ break;
+ }
+ return order;
+ }
+
+
+/**
+ convert search attribute parameter values defined in PBAP specification to internal enum
+*/
+SymbianPBAP::TSearchAttribute CPbapAppHeader::ConvertToSearchAttribute(TUint8 aValue) const
+ {
+ LOG_FUNC
+ SymbianPBAP::TSearchAttribute searchAttrib;
+ switch (aValue)
+ {
+ case 0x00:
+ searchAttrib = SymbianPBAP::EName;
+ break;
+ case 0x01:
+ searchAttrib = SymbianPBAP::ENumber;
+ break;
+ case 0x02:
+ searchAttrib = SymbianPBAP::ESound;
+ break;
+ default:
+ searchAttrib = SymbianPBAP::EUnknownSearchAttribute;
+ break;
+ }
+ return searchAttrib;
+ }
+
+/**
+ convert format parameter values defined in PBAP specification to internal enum
+*/
+TVCardVersion CPbapAppHeader::ConvertToVCardVersionL(TUint8 aValue) const
+ {
+ LOG_FUNC
+ TVCardVersion version = EPBAPVCard21;
+ switch (aValue)
+ {
+ case 0x00:
+ version = EPBAPVCard21;
+ break;
+ case 0x01:
+ version = EPBAPVCard30;
+ break;
+ default:
+ User::Leave(KErrArgument);
+ break;
+ }
+ return version;
+ }
+
+/**
+ Converts big-endian formatted descriptor to 64-bit filter mask
+*/
+TUint64 CPbapAppHeader::ConvertToFilter(const TUint8* aPtr) const
+ {
+ LOG_FUNC
+ return ((static_cast<TUint64>(aPtr[0])<<56) |
+ (static_cast<TUint64>(aPtr[1])<<48) |
+ (static_cast<TUint64>(aPtr[2])<<40) |
+ (static_cast<TUint64>(aPtr[3])<<32) |
+ (static_cast<TUint64>(aPtr[4])<<24) |
+ (static_cast<TUint64>(aPtr[5])<<16) |
+ (static_cast<TUint64>(aPtr[6])<<8) |
+ (static_cast<TUint64>(aPtr[7])));
+ }
+
+/**
+Determine the actual PBAP operation from the type header and the parsed
+application parameter header
+*/
+TPbapOperation CPbapAppHeader::DeterminePBAPOperationL(const TDesC8& aTypeHeader)
+ {
+ LOG_FUNC
+
+#ifdef __FLOG_ACTIVE
+ RBuf buf;
+ buf.CreateL(aTypeHeader.Length());
+ buf.Copy(aTypeHeader);
+ LOG1(_L("Type header: %S"), &buf);
+ buf.Close();
+#endif
+
+ TPtrC8 typeHeader(aTypeHeader);
+ TInt length = aTypeHeader.Length();
+
+ // obex may append null terminator to type header, if so remove it
+ if (length && aTypeHeader[length-1]=='\0')
+ {
+ typeHeader.Set(aTypeHeader.Left(length-1));
+ }
+
+ if (typeHeader.CompareF(KObexTypeBTvCardPhoneBook)==0)
+ {
+ if (!iTagsPresent[EMaxListCount])
+ {
+ LOG(_L("Missing mandatory MaxListCount tag in App Header"));
+ // mandatory to have the tag present in this operation
+ User::Leave(KErrArgument);
+ }
+ if (iMaxListCount==0)
+ {
+ iOperation = ERequestPhoneBookSize;
+ LOG(_L("PBAP operation is PullPhoneBook - MaxListCount = 0"));
+ }
+ else
+ {
+ iOperation = EPullPhoneBook;
+ LOG(_L("PBAP operation is PullPhoneBook"));
+ }
+
+ // this type of request operates on absolute paths
+ iIsAbsolutePathOp = ETrue;
+ }
+ else if (typeHeader.CompareF(KObexTypeBTvCardListing)==0)
+ {
+ if (!iTagsPresent[EMaxListCount])
+ {
+ LOG(_L("Missing MaxListCount tag in App Header, continuing due to spec (v1.0) inconsistency"));
+ }
+ if (iMaxListCount==0)
+ {
+ iOperation = ERequestPhoneBookSize;
+ LOG(_L("PBAP operation is PullvCardListing - MaxListCount = 0"));
+ }
+ else
+ {
+ iOperation = EPullVCardListing;
+ LOG(_L("PBAP operation is PullvCardListing"));
+ }
+ }
+ else if (typeHeader.CompareF(KObexTypeBTvCard)==0)
+ {
+ // leave to folderparser to determine if handle is ok
+ iOperation = EPullVCard;
+ LOG(_L("PBAP operation is PullvCard"));
+ }
+ else
+ {
+ // incorrect or nonexistent Type header. Bad.
+ LOG(_L("Cannot determine PBAP operation"));
+ User::Leave(KErrCorrupt);
+ }
+
+ return iOperation;
+ }