bluetooth/btsdp/database/SDPServiceRecord.cpp
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2000-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 <btsdp.h>
       
    18 #include "attrvalueencoded.h"
       
    19 #include "sdpconsts.h"
       
    20 #include "SDPServiceRecord.h"
       
    21 #include "sdputil.h"
       
    22 
       
    23 
       
    24 // ******************* CSdpServRecord ********************************
       
    25 
       
    26 EXPORT_C CSdpServRecord *CSdpServRecord::NewL()
       
    27 	{
       
    28 	CSdpServRecord *self=new (ELeave) CSdpServRecord(KNullUid);
       
    29 	CleanupStack::PushL(self);
       
    30 	self->ConstructL();
       
    31 	CleanupStack::Pop();
       
    32 	return self;
       
    33 	}
       
    34 
       
    35 EXPORT_C CSdpServRecord *CSdpServRecord::NewServerSideL(const TUid& aUid)
       
    36 	{
       
    37 	CSdpServRecord *self=new (ELeave) CSdpServRecord(aUid);
       
    38 	CleanupStack::PushL(self);
       
    39 	self->ConstructL();
       
    40 	CleanupStack::Pop();
       
    41 	return self;
       
    42 	}
       
    43 
       
    44 CSdpServRecord::CSdpServRecord(const TUid& aClientUid)
       
    45 	: iAttributes(CSdpAttr::LinkOffset()), iClientUid(aClientUid)
       
    46 	{
       
    47 	}
       
    48 
       
    49 void CSdpServRecord::ConstructL()
       
    50 	{
       
    51 	TPckg<TUint> intBuf(0);
       
    52 	iRecordState = CSdpAttrValueUint::NewUintL(intBuf);
       
    53 
       
    54 	// Create the buffer the correct size for storing a Uint
       
    55 	TInt encodedSize = TElementEncoder::EncodedSize(iRecordState->Type(), iRecordState->DataSize());
       
    56 	iEncodeBuf.CreateL(encodedSize);
       
    57 	TElementEncoder encoder(iEncodeBuf);
       
    58 
       
    59 	iEncoderVisitor = CAttrEncoderVisitor::NewL(encoder);
       
    60 	}
       
    61 
       
    62 
       
    63 CSdpServRecord::~CSdpServRecord()
       
    64 	{
       
    65 	// Delete all attributes on the attribute list
       
    66 	iAttributes.ResetAndDestroy();
       
    67 	
       
    68 	// Remove this servRecord from any Q it might be on
       
    69 	iLink.Deque();
       
    70 
       
    71 	delete iEncoderVisitor;
       
    72 	delete iRecordState;
       
    73 	iEncodeBuf.Close();
       
    74 	}
       
    75 
       
    76 // handle may be encoded
       
    77 EXPORT_C TSdpServRecordHandle CSdpServRecord::Handle() const
       
    78 	{
       
    79 	__ASSERT_ALWAYS(!iAttributes.IsEmpty(), DbPanic(ESdpDbRecordBadHandle));
       
    80 
       
    81 	CSdpAttr *first = iAttributes.First();
       
    82 	__ASSERT_ALWAYS(first->AttributeID() == 0, DbPanic(ESdpDbRecordBadHandle));
       
    83 //	__ASSERT_ALWAYS(first->Value().Type() == ETypeUint, DbPanic(ESdpDbRecordBadHandle));
       
    84 // needs to test for an encoded value, can we decode ?
       
    85 
       
    86 	TSdpServRecordHandle retVal;
       
    87 	TUint8* ptr = (TUint8*)first->Value().Des().Ptr();
       
    88  
       
    89 	switch (first->Value().Type())
       
    90 		{
       
    91 		case ETypeUint:
       
    92 			retVal = first->Value().Uint();
       
    93 			break;
       
    94 		case ETypeEncoded:
       
    95 			{
       
    96 			const TUint8 KTUint32Header = (ETypeUint << KSdpElemHdrTypeShift) | ESizeFourBytes;
       
    97 			if (*ptr++ != KTUint32Header) DbPanic(ESdpAttrValueBadSize);
       
    98 			retVal = BigEndian::Get32(ptr);
       
    99 			}
       
   100 			break;
       
   101 		default:
       
   102 			DbPanic(ESdpDbRecordBadHandle);
       
   103 			return 0;	// no warnings
       
   104 		}
       
   105 	return retVal;
       
   106 	}
       
   107 
       
   108 EXPORT_C TUid CSdpServRecord::ClientUid() const
       
   109 	{
       
   110 	return iClientUid;
       
   111 	}
       
   112 
       
   113 /**
       
   114 @see RecordStateChange
       
   115 */
       
   116 EXPORT_C void CSdpServRecord::AddAttribute(CSdpAttr* aAttr)
       
   117 /**
       
   118 	This function adds an attribute to this record
       
   119 **/
       
   120 	{
       
   121 	iAttributes.AddInOrder(*aAttr);
       
   122 	}
       
   123 
       
   124 /**
       
   125 If an attribute for this record is updated or deleted this method
       
   126 shall be called.  It will update the state attribute, which may
       
   127 be used by remote devices to aid caching.
       
   128 
       
   129 @internalTechnology
       
   130 @released
       
   131 */
       
   132 EXPORT_C void CSdpServRecord::RecordStateChange()
       
   133 	{
       
   134 	TDblQueIter<CSdpAttr> attrIter(iAttributes);
       
   135 	CSdpAttr* attr = attrIter++;
       
   136 
       
   137 	while(attr)
       
   138 		{
       
   139 		if(attr->AttributeID() == KSdpAttrIdServiceRecordState)
       
   140 			{
       
   141 			TUint state = iRecordState->Uint();
       
   142 
       
   143 			TPckg<TUint> stateBuf(0);
       
   144 			SdpUtil::PutUint(&stateBuf[0], ++state, sizeof(TUint));
       
   145 
       
   146 			iRecordState->SetUintValue(stateBuf);
       
   147 
       
   148 			// This encodes iRecordState into the buffer provided at construction
       
   149 			iEncodeBuf.SetLength(0);
       
   150 			TRAPD(err, iEncoderVisitor->EncodeAttributeL(*iRecordState));
       
   151 			// Attribute encoding can only fail if the attribute is of an unknown type 
       
   152 			// or the supplied buffer is too small.  We have set the length of the
       
   153 			// buffer to the correct length on creation so that will not fail.
       
   154 			// We know iRecordState is a CSdpAttrValueUint so cannot fail.
       
   155 			__ASSERT_ALWAYS(!err, DbPanic(ESdpDbAttributeEncodingFailed));
       
   156 
       
   157 			__ASSERT_ALWAYS(attr->Value().Type() == ETypeEncoded, DbPanic(ESdpDbStoredAttrValNotEncoded));
       
   158 			reinterpret_cast<CSdpAttrValueEncoded&>(attr->Value()).SetEncodedValue(iEncodeBuf);
       
   159 
       
   160 			break;
       
   161 			}
       
   162 		attr = attrIter++;
       
   163 		}
       
   164 	}
       
   165 
       
   166 MSdpElementBuilder *CSdpServRecord::BuildUintL(const TDesC8& aUint)
       
   167 /**
       
   168 	This function builds a new attribute
       
   169 **/
       
   170 	{
       
   171 	TUint16 id=0;
       
   172 	TInt len = aUint.Length();
       
   173 	
       
   174 	if (len==1)
       
   175 		id = aUint[0];	// Strictly this is an error
       
   176 	else if (len==2)
       
   177 		id = BigEndian::Get16(&aUint[0]);
       
   178 	else
       
   179 		User::Leave(KErrSdpBadAttributeId);
       
   180 
       
   181 	CSdpAttr *attr=CSdpAttr::NewL(id,this);
       
   182 	iAttributes.AddInOrder(*attr);
       
   183 	return attr;
       
   184 	}
       
   185 
       
   186 EXPORT_C CRecordAttr::CRecordAttr()
       
   187 : iValue(0)
       
   188 	{
       
   189 	}
       
   190 
       
   191 EXPORT_C CRecordAttr::~CRecordAttr()
       
   192 	{
       
   193 	}
       
   194 
       
   195 MSdpElementBuilder* CRecordAttr::BuildUintL(const TDesC8& aUint)
       
   196 	{
       
   197 	iValue = SdpUtil::GetUint(aUint);
       
   198 	return this;
       
   199 	}