obex/obexprotocol/obex/src/obexobjectexpandedbaseobject.cpp
changeset 0 d0791faffa3f
equal deleted inserted replaced
-1:000000000000 0:d0791faffa3f
       
     1 // Copyright (c) 1997-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 /**
       
    17  @file
       
    18  @internalComponent
       
    19 */
       
    20 
       
    21 #include <obex.h>
       
    22 #include <obex/internal/obexinternalheader.h>
       
    23 #include <obex/internal/obexpacket.h>
       
    24 #include "logger.h"
       
    25 #include "OBEXUTIL.H"
       
    26 #include "obexheaderutil.h"
       
    27 
       
    28 IF_FLOGGING(_LIT8(KLogComponent, "obex");)
       
    29 
       
    30 /**
       
    31 Default constructor for ObexObjects
       
    32 @internalComponent
       
    33 */
       
    34 CObexBaseObject::CObexBaseObject()
       
    35 	{
       
    36 	ResetHeaders();
       
    37 	}
       
    38 
       
    39 /** 
       
    40 Destructor. 
       
    41 */
       
    42 CObexBaseObject::~CObexBaseObject()
       
    43 	{
       
    44 	FLOG(_L("CObexBaseObject Destructor\r\n"));
       
    45 	ResetHeaders();
       
    46 	if (iObexHeader)
       
    47 		{
       
    48 		delete iObexHeader;
       
    49 		}
       
    50 	
       
    51 	delete iHeaderSet;
       
    52 	}
       
    53 
       
    54 /**
       
    55 Sets header mask to 1's (include all), but valid mask to 0's (none valid).
       
    56 Also reset progress indicators to avoid any un-initialised transfer attempts
       
    57 @internalComponent
       
    58 */
       
    59 void CObexBaseObject::ResetHeaders()
       
    60 	{
       
    61 	iHeaderMask = 0xFFFF;
       
    62 	iValidHeaders = 0x0000;
       
    63 	iSendProgress = EError;
       
    64 	iRecvProgress = EError;
       
    65 	iRecvBytes = 0;
       
    66 	
       
    67 	if (iHttp)
       
    68 		{
       
    69 		iHttp->ResetAndDestroy();
       
    70 		delete iHttp;
       
    71 		iHttp = NULL;
       
    72 		}
       
    73 
       
    74 	// Here iHeaderSet can be NULL. This method is called in 
       
    75 	// CObexBaseObject::CObexBaseObject() that is called before the 
       
    76 	// derived class ConstructL() method. iHeaderSet is constructed in 
       
    77 	// CreateHeaderStorageDataL() called from ConstructL(). 
       
    78 	// So, in the constructor it is always NULL.
       
    79 	// This method is also called in CObexBaseObject::Reset() where iHeaderSet
       
    80 	// will be valid.
       
    81 	
       
    82 	if (iHeaderSet)
       
    83 		{
       
    84 		iHeaderSet->SetMask(NULL);
       
    85 		while (iHeaderSet->Count())
       
    86 			{
       
    87 			iHeaderSet->DeleteCurrentHeader();
       
    88 			}
       
    89 		}
       
    90 	}
       
    91 
       
    92 /**
       
    93 @internalComponent
       
    94 */
       
    95 void CObexBaseObject::CreateHeaderStorageDataL()
       
    96 	{
       
    97 	__ASSERT_DEBUG(!iHeaderSet, IrOBEXUtil::Panic(ENotNullPointer));	
       
    98 	iHeaderSet = CObexHeaderSet::NewL();
       
    99 
       
   100 	if (iObexHeader == NULL)
       
   101 		{
       
   102 		iObexHeader = CObexHeader::NewL();
       
   103 		}
       
   104 	}
       
   105 
       
   106 /**
       
   107 Set the connection id.
       
   108 This method will check the headerset for a connectionId header. If one if located,
       
   109 then this will be modified for the new HV value. If not, a new connectionId header
       
   110 will be added.
       
   111 
       
   112 @param aFourByte The connectionID to be set
       
   113 @internalComponent
       
   114 */
       
   115 void CObexBaseObject::SetConnectionIdL(TUint32 aFourByte)
       
   116 	{
       
   117 	FLOG(_L(">>CObexBaseObject::SetConnectionIdL"));
       
   118 	
       
   119 	__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
   120 	
       
   121 	//reset the mask so all headers are searched
       
   122 	//NB. SetMask sets the iterator at the start of the headerset
       
   123 	iHeaderSet->SetMask(NULL);
       
   124 
       
   125 	if (iHeaderSet->Find(TObexInternalHeader::EConnectionID, *iObexHeader) == KErrNone)
       
   126 		{
       
   127 		iHeaderSet->DeleteCurrentHeader();
       
   128 		}
       
   129 
       
   130     CObexHeader* header = CObexHeader::NewL();
       
   131 	CleanupStack::PushL(header);
       
   132 	header->SetFourByte(TObexInternalHeader::EConnectionID, aFourByte);
       
   133 
       
   134 	//Transfer ownership of pointer to CObexHeaderSet
       
   135 	LEAVEIFERRORL(iHeaderSet->AddHeader(header));
       
   136 	CleanupStack::Pop(header);
       
   137 		
       
   138 	iValidHeaders |= KObexHdrConnectionID;
       
   139 	iHeaderMask |= KObexHdrConnectionID;
       
   140 
       
   141 	FLOG(_L("<<CObexBaseObject::SetConnectionIdL"));
       
   142 	}
       
   143 
       
   144 /**
       
   145 Returns the connection ID.
       
   146 
       
   147 @return	Returns KConnIDInvalid if no connectionID is set.
       
   148 @internalComponent
       
   149 */
       
   150 TUint32 CObexBaseObject::ConnectionID()
       
   151 	{
       
   152 	if (iValidHeaders & KObexHdrConnectionID)
       
   153 		{
       
   154 		__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
   155 		
       
   156 		//reset the mask so all headers are searched
       
   157 		//NB. SetMask sets the iterator at the start of the headerset
       
   158 		iHeaderSet->SetMask(NULL);
       
   159 
       
   160 		if (iHeaderSet->Find(TObexInternalHeader::EConnectionID, *iObexHeader) == KErrNone)
       
   161 			{
       
   162 			return (iObexHeader->AsFourByte());
       
   163 			}
       
   164 		else
       
   165 			{
       
   166 			return KConnIDInvalid;
       
   167 			}
       
   168 		}
       
   169 	else
       
   170 		{
       
   171 		return KConnIDInvalid;
       
   172 		}
       
   173 	}
       
   174 
       
   175 /** 
       
   176 Sets the Name attribute of the object.
       
   177 
       
   178 The Name is used to identify the object to the remote machine (or to identify 
       
   179 a received object). Note that in general, this is quite distinct from the 
       
   180 CObexFileObject::DataFile() attribute, which specifies where the body of the 
       
   181 object is stored. 
       
   182 
       
   183 @param aDesc Name attribute 
       
   184 	
       
   185 @publishedAll
       
   186 @released
       
   187 */
       
   188 EXPORT_C void CObexBaseObject::SetNameL (const TDesC& aDesc)
       
   189 	{
       
   190 	LOG_LINE
       
   191 	LOG_FUNC
       
   192 
       
   193 	__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
   194 	
       
   195 	//reset the mask so all headers are searched
       
   196 	//NB. SetMask sets the iterator at the start of the headerset
       
   197 	iHeaderSet->SetMask(NULL);
       
   198 
       
   199 	if (iHeaderSet->Find(TObexInternalHeader::EName, *iObexHeader) == KErrNone)
       
   200 		{
       
   201 		iHeaderSet->DeleteCurrentHeader();
       
   202 		}
       
   203 
       
   204     CObexHeader* header = CObexHeader::NewL();
       
   205 	CleanupStack::PushL(header);
       
   206 	header->SetUnicodeL(TObexInternalHeader::EName, aDesc);
       
   207 	//Transfer ownership of pointer to CObexHeaderSet
       
   208 	LEAVEIFERRORL(iHeaderSet->AddHeader(header));
       
   209 	CleanupStack::Pop(header);
       
   210 	
       
   211 	iValidHeaders |= KObexHdrName;
       
   212 	}
       
   213 
       
   214 /** 
       
   215 Sets the Type attribute of the object. 
       
   216 
       
   217 This should be in the form of a valid IANA media type (see http://www.iana.org/assignments/media-types/index.html).
       
   218 
       
   219 @param aDesc Type attribute 
       
   220 	
       
   221 @publishedAll
       
   222 @released
       
   223 */
       
   224 EXPORT_C void CObexBaseObject::SetTypeL (const TDesC8& aDesc)
       
   225 	{
       
   226 	LOG_LINE
       
   227 	LOG_FUNC
       
   228 
       
   229 	TInt len = aDesc.Length();
       
   230 	// make sure length does not include any null terms
       
   231 	while(len && aDesc[len - 1] == 0)
       
   232 		{
       
   233 		--len;
       
   234 		};
       
   235 	TPtrC8 src = aDesc.Left(len);
       
   236 
       
   237 	//leave room for exactly one null term
       
   238 	HBufC8* buf = HBufC8::NewL(src.Length() + 1);
       
   239 	CleanupStack::PushL(buf);
       
   240 	TPtr8 type(buf->Des());
       
   241 	type.Copy(src);
       
   242 	type.Append(0);
       
   243 
       
   244 	__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
   245 	
       
   246 	//reset the mask so all headers are searched
       
   247 	//NB. SetMask sets the iterator at the start of the headerset
       
   248 	iHeaderSet->SetMask(NULL);
       
   249 
       
   250 	if (iHeaderSet->Find(TObexInternalHeader::EType, *iObexHeader) == KErrNone)
       
   251 		{
       
   252 		iHeaderSet->DeleteCurrentHeader();
       
   253 		}
       
   254 
       
   255     CObexHeader* header = CObexHeader::NewL();
       
   256 	CleanupStack::PushL(header);
       
   257 	header->SetByteSeqL(TObexInternalHeader::EType, type);
       
   258 
       
   259 	//Transfer ownership of pointer to CObexHeaderSet
       
   260 	LEAVEIFERRORL(iHeaderSet->AddHeader(header));
       
   261 	CleanupStack::Pop(header);
       
   262 
       
   263 	CleanupStack::PopAndDestroy(buf);
       
   264 
       
   265 	iValidHeaders |= KObexHdrType;
       
   266 
       
   267 	}
       
   268 
       
   269 /** 
       
   270 Sets the Length attribute of the object, in bytes. 
       
   271 
       
   272 Note that this does not necessarily have to match the exact size of the body 
       
   273 data, but is used to give an indication of the size to the receiving end.
       
   274 
       
   275 @param aLength Length attribute of the object 
       
   276 	
       
   277 @publishedAll
       
   278 @released
       
   279 */
       
   280 EXPORT_C void CObexBaseObject::SetLengthL (const TUint32 aLength)
       
   281 	{
       
   282 	LOG_LINE
       
   283 	LOG_FUNC
       
   284 
       
   285 	__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
   286 	
       
   287 	//reset the mask so all headers are searched
       
   288 	//NB. SetMask sets the iterator at the start of the headerset
       
   289 	iHeaderSet->SetMask(NULL);
       
   290 
       
   291 	if (iHeaderSet->Find(TObexInternalHeader::ELength, *iObexHeader) == KErrNone)
       
   292 		{
       
   293 		iHeaderSet->DeleteCurrentHeader();
       
   294 		}
       
   295 
       
   296     CObexHeader* header = CObexHeader::NewL();
       
   297 	CleanupStack::PushL(header);
       
   298 	header->SetFourByte(TObexInternalHeader::ELength, aLength);
       
   299 	//Transfer ownership of pointer to CObexHeaderSet
       
   300 	LEAVEIFERRORL(iHeaderSet->AddHeader(header));
       
   301 	CleanupStack::Pop(header);
       
   302 
       
   303 	iValidHeaders |= KObexHdrLength;
       
   304 	}
       
   305 
       
   306 /** 
       
   307 Sets the Time attribute of the object (stored in UTC).
       
   308 
       
   309 @param aLocalTime Time attribute in local time
       
   310 	
       
   311 @publishedAll
       
   312 @released
       
   313 */
       
   314 EXPORT_C void CObexBaseObject::SetTimeL (const TTime aLocalTime)
       
   315 	{
       
   316 	LOG_LINE
       
   317 	LOG_FUNC
       
   318 
       
   319 	// Convert local time to UTC
       
   320 	TTime utcTime(aLocalTime);
       
   321 	utcTime -= User::UTCOffset();
       
   322 	SetUtcTimeL(utcTime);
       
   323 	}
       
   324 
       
   325 /** 
       
   326 Sets the Time attribute of the object (stored in UTC).
       
   327 
       
   328 @param aUtcTime Time attribute in local time
       
   329 */
       
   330 void CObexBaseObject::SetUtcTimeL (const TTime aUtcTime)
       
   331 	{
       
   332 	LOG_LINE
       
   333 	LOG_FUNC
       
   334 
       
   335 	TBuf<16> timebuf;
       
   336 	aUtcTime.FormatL(timebuf, _L("%F%Y%M%DT%H%T%SZ"));
       
   337 	TBuf8<16> narrowBuf;
       
   338 	narrowBuf.Copy(timebuf);
       
   339 	SetTimeHeaderL(narrowBuf);
       
   340 
       
   341 	iValidHeaders |= KObexHdrTime;
       
   342 	}
       
   343 
       
   344 /**
       
   345 Add a descriptor as the one and only Time header in an object.
       
   346 
       
   347 @param aTimeDes A narrow descriptor which will be stored in the object.
       
   348 */
       
   349 void CObexBaseObject::SetTimeHeaderL(const TDesC8& aTimeDes)
       
   350 	{
       
   351 	LOG_LINE
       
   352 	LOG_FUNC
       
   353 
       
   354 	__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
   355 	
       
   356 	//reset the mask so all headers are searched
       
   357 	//NB. SetMask sets the iterator at the start of the headerset
       
   358 	iHeaderSet->SetMask(NULL);
       
   359 
       
   360 	if (iHeaderSet->Find(TObexInternalHeader::ETime, *iObexHeader) == KErrNone)
       
   361 		{
       
   362 		iHeaderSet->DeleteCurrentHeader();
       
   363 		}
       
   364 	
       
   365 	CObexHeader* header = CObexHeader::NewL();
       
   366 	CleanupStack::PushL(header);
       
   367 	header->SetByteSeqL(TObexInternalHeader::ETime, aTimeDes);
       
   368 
       
   369 	//Transfer ownership of pointer to CObexHeaderSet
       
   370 	LEAVEIFERRORL(iHeaderSet->AddHeader(header));
       
   371 	CleanupStack::Pop(header);
       
   372 	}
       
   373 
       
   374 /** 
       
   375 Sets the Description attribute of the object. 
       
   376 
       
   377 This is currently the easiest way to send proprietary information along with 
       
   378 an object.
       
   379 
       
   380 @param aDesc Description attribute 
       
   381 	
       
   382 @publishedAll
       
   383 @released
       
   384 */
       
   385 EXPORT_C void CObexBaseObject::SetDescriptionL (const TDesC& aDesc)
       
   386 	{
       
   387 	LOG_LINE
       
   388 	LOG_FUNC
       
   389 
       
   390 	__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
   391 	
       
   392 	//reset the mask so all headers are searched
       
   393 	//NB. SetMask sets the iterator at the start of the headerset
       
   394 	iHeaderSet->SetMask(NULL);
       
   395 
       
   396 	if (iHeaderSet->Find(TObexInternalHeader::EDescription, *iObexHeader) == KErrNone)
       
   397 		{
       
   398 		iHeaderSet->DeleteCurrentHeader();
       
   399 		}
       
   400 
       
   401     CObexHeader* header = CObexHeader::NewL();
       
   402 	CleanupStack::PushL(header);
       
   403 	header->SetUnicodeL(TObexInternalHeader::EDescription, aDesc);
       
   404 	//Transfer ownership of pointer to CObexHeaderSet
       
   405 	LEAVEIFERRORL(iHeaderSet->AddHeader(header));
       
   406 	CleanupStack::Pop(header);
       
   407 
       
   408 	iValidHeaders |= KObexHdrDescription;
       
   409 	}
       
   410 
       
   411 /**	
       
   412 Sets the Application Parameters attribute of the object.
       
   413 
       
   414   This is expected to be of the format Tag-Length-Value, but this is not enforced.
       
   415   
       
   416 @param aDesc Application Parameters attribute 
       
   417 	
       
   418 @publishedAll
       
   419 @released
       
   420 */
       
   421 EXPORT_C void CObexBaseObject::SetAppParamL (const TDesC8& aDesc)
       
   422 	{
       
   423 	LOG_LINE
       
   424 	LOG_FUNC
       
   425 
       
   426 	FLOG(_L("CObexBaseObject::SetAppParamL"));
       
   427 
       
   428 	__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
   429 	
       
   430 	//reset the mask so all headers are searched
       
   431 	//NB. SetMask sets the iterator at the start of the headerset
       
   432 	iHeaderSet->SetMask(NULL);
       
   433 
       
   434 	if (iHeaderSet->Find(TObexInternalHeader::EAppParam, *iObexHeader) == KErrNone)
       
   435 		{
       
   436 		iHeaderSet->DeleteCurrentHeader();
       
   437 		}
       
   438 	CObexHeader* header = CObexHeader::NewL();
       
   439 	CleanupStack::PushL(header);
       
   440 	header->SetByteSeqL(TObexInternalHeader::EAppParam, aDesc);
       
   441 	//Transfer ownership of pointer to CObexHeaderSet
       
   442 	LEAVEIFERRORL(iHeaderSet->AddHeader(header));
       
   443 	CleanupStack::Pop(header);
       
   444 	
       
   445 	iValidHeaders |= KObexHdrAppParam;
       
   446 	}
       
   447 
       
   448 /** 
       
   449 Sets the Target attribute of the object.
       
   450 
       
   451 Generally, this will only have any useful meaning if the session Who attribute 
       
   452 of the remote machine is recognised, and particularly, when connected to a 
       
   453 strict peer (see CObex::IsStrictPeer()).
       
   454 
       
   455 @param aDesc Target attribute 
       
   456 	
       
   457 @publishedAll
       
   458 @released
       
   459 */
       
   460 EXPORT_C void CObexBaseObject::SetTargetL (const TDesC8& aDesc)
       
   461 	{
       
   462 	LOG_LINE
       
   463 	LOG_FUNC
       
   464 
       
   465 	__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
   466 	
       
   467 	//reset the mask so all headers are searched
       
   468 	//NB. SetMask sets the iterator at the start of the headerset
       
   469 	iHeaderSet->SetMask(NULL);
       
   470 
       
   471 	if (iHeaderSet->Find(TObexInternalHeader::ETarget, *iObexHeader) == KErrNone)
       
   472 		{
       
   473 		iHeaderSet->DeleteCurrentHeader();
       
   474 		}
       
   475 
       
   476 	CObexHeader* header = CObexHeader::NewL();
       
   477 	CleanupStack::PushL(header);
       
   478 	header->SetByteSeqL(TObexInternalHeader::ETarget, aDesc);
       
   479 	//Transfer ownership of pointer to CObexHeaderSet
       
   480 	LEAVEIFERRORL(iHeaderSet->AddHeader(header));
       
   481 	CleanupStack::Pop(header);
       
   482 
       
   483 	iValidHeaders |= KObexHdrTarget;
       
   484 	}
       
   485 
       
   486 /** 
       
   487 Add an Http header.
       
   488 
       
   489 @param aDesc HTTP header to be added to the object's collection of HTTP headers 
       
   490 	
       
   491 @publishedAll
       
   492 @released
       
   493 */
       
   494 EXPORT_C void CObexBaseObject::AddHttpL (const TDesC8& aDesc)
       
   495 	{
       
   496 	LOG_LINE
       
   497 	LOG_FUNC
       
   498 
       
   499     CObexHeader* header = CObexHeader::NewL();
       
   500 	CleanupStack::PushL(header);
       
   501 	header->SetByteSeqL(TObexInternalHeader::EHttp, aDesc);
       
   502 	
       
   503 	__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
   504 	
       
   505 	//Transfer ownership of pointer to CObexHeaderSet
       
   506 	LEAVEIFERRORL(iHeaderSet->AddHeader(header));
       
   507 	CleanupStack::Pop(header);
       
   508 
       
   509 	if (!iHttp)
       
   510 		{
       
   511 		iHttp = new(ELeave) RPointerArray<HBufC8>(2);
       
   512 		}
       
   513 	
       
   514 	HBufC8* buf = aDesc.AllocLC();
       
   515 	LEAVEIFERRORL(iHttp->Append(buf));
       
   516 	CleanupStack::Pop(buf);
       
   517 	
       
   518 	iValidHeaders |= KObexHdrHttp;  
       
   519 	}
       
   520 
       
   521 /**
       
   522 Adds a CObexHeader into the CObexHeaderSet
       
   523 
       
   524 @param aHeader A Pointer to a CObexHeader to be added to the CObexHeaderSet
       
   525 	
       
   526 @publishedAll
       
   527 @released
       
   528 */
       
   529 EXPORT_C void CObexBaseObject::AddHeaderL(CObexHeader& aHeader)
       
   530 	{
       
   531 	LOG_LINE
       
   532 	LOG_FUNC
       
   533 
       
   534 	if (aHeader.HI() == TObexInternalHeader::EHttp)
       
   535 		{
       
   536 		// Add the HTTP header into the iHttp array to keep old and new
       
   537 		// http header storage consistent.
       
   538 		//
       
   539 		if (!iHttp)
       
   540 			{
       
   541 			iHttp = new(ELeave) RPointerArray<HBufC8>(2);
       
   542 			}
       
   543 	
       
   544 		HBufC8* buf = (aHeader.AsByteSeq()).AllocLC();
       
   545 		LEAVEIFERRORL(iHttp->Append(buf));
       
   546 		CleanupStack::Pop();
       
   547 	
       
   548 		iValidHeaders |= KObexHdrHttp;  
       
   549 		}
       
   550 
       
   551 	__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
   552 	
       
   553 	//Transfer ownership of pointer to CObexHeaderSet
       
   554 	LEAVEIFERRORL(iHeaderSet->AddHeader(&aHeader));
       
   555 
       
   556 	switch (aHeader.HI())
       
   557 		{
       
   558 	case (TObexInternalHeader::EName) :
       
   559 		{
       
   560 		iValidHeaders |= KObexHdrName;  
       
   561 		break;
       
   562 		}
       
   563 	case (TObexInternalHeader::EType) :
       
   564 		{
       
   565 		iValidHeaders |= KObexHdrType;  
       
   566 		break;
       
   567 		}
       
   568 	case (TObexInternalHeader::ETime) :
       
   569 		{
       
   570 		iValidHeaders |= KObexHdrTime;  
       
   571 		break;
       
   572 		}
       
   573 	case (TObexInternalHeader::EConnectionID) :
       
   574 		{
       
   575 		iValidHeaders |= KObexHdrConnectionID;  
       
   576 		break;
       
   577 		}
       
   578 	case (TObexInternalHeader::ELength) :
       
   579 		{
       
   580 		iValidHeaders |= KObexHdrLength;  
       
   581 		break;
       
   582 		}
       
   583 	case (TObexInternalHeader::EDescription) :
       
   584 		{
       
   585 		iValidHeaders |= KObexHdrDescription;  
       
   586 		break;
       
   587 		}
       
   588 	case (TObexInternalHeader::ECount) :
       
   589 		{
       
   590 		iValidHeaders |= KObexHdrCount;  
       
   591 		break;
       
   592 		}
       
   593 	case (TObexInternalHeader::EAppParam) :
       
   594 		{
       
   595 		iValidHeaders |= KObexHdrAppParam;  
       
   596 		break;
       
   597 		}
       
   598 	case (TObexInternalHeader::ETarget) :
       
   599 		{
       
   600 		iValidHeaders |= KObexHdrTarget;  
       
   601 		break;
       
   602 		}
       
   603 	case (TObexInternalHeader::ECreatorID) :
       
   604 		{
       
   605 		iValidHeaders |= KObexHdrCreatorID;  
       
   606 		break;
       
   607 		}
       
   608 	case (TObexInternalHeader::EWanUUID) :
       
   609 		{
       
   610 		iValidHeaders |= KObexHdrWanUUID;  
       
   611 		break;
       
   612 		}
       
   613 	case (TObexInternalHeader::EObjectClass) :
       
   614 		{
       
   615 		iValidHeaders |= KObexHdrObjectClass;  
       
   616 		break;
       
   617 		}
       
   618 	case (TObexInternalHeader::EEndOfBody) :
       
   619 		{
       
   620 		__ASSERT_ALWAYS(DataSize() == 0, IrOBEXUtil::Panic(EAddingInvalidEoBHeader));
       
   621 		iValidHeaders |= KObexHdrEndOfBody;
       
   622 		break;
       
   623 		}
       
   624 	default : 
       
   625 		{
       
   626 		if ((aHeader.HI() & 0x30) != 0)
       
   627 			{
       
   628 			iValidHeaders |= KObexHdrUserDefined;  
       
   629 			}
       
   630 		break;
       
   631 		}
       
   632 	}
       
   633 	}
       
   634 
       
   635 /** 
       
   636 Resets the object, to make it represent nothing. 
       
   637 
       
   638 Call this before setting a CObexObject to represent a new object. 
       
   639 	
       
   640 @publishedAll
       
   641 @released
       
   642 */
       
   643 EXPORT_C void CObexBaseObject::Reset()
       
   644 	{
       
   645 	LOG_LINE
       
   646 	LOG_FUNC
       
   647 
       
   648 	ResetHeaders();
       
   649 	ResetData();
       
   650 	}
       
   651 
       
   652 /**
       
   653 Makes a first level guess at setting the mime type from the
       
   654 file extension.
       
   655 
       
   656 This API is deprecated and may be removed at any time. For any production 
       
   657 applications, the versit and the Application architecture (see 
       
   658 RApaLsSession::RecognizeData) provide far more flexibilty and robustness.
       
   659 
       
   660 @deprecated 6.1
       
   661 @internalComponent
       
   662 */
       
   663 void CObexBaseObject::GuessTypeFromExtL(const TDesC& aExt)
       
   664 	{
       
   665 	_LIT(KVcfType, ".vcf");
       
   666 	_LIT(KVcsType, ".vcs");
       
   667 	_LIT(KTxtType, ".txt");
       
   668 	_LIT8(KVcard, "text/x-vCard");
       
   669 	_LIT8(KVcalendar, "text/x-vCalendar");
       
   670 	_LIT8(KTextPlain, "text/plain");
       
   671 	
       
   672 	iValidHeaders &= ~KObexHdrType;	// Default, if no others match
       
   673 	if(!aExt.CompareC(KVcfType))
       
   674 		{
       
   675 		SetTypeL(KVcard);
       
   676 		return;
       
   677 		}
       
   678     if(!aExt.CompareC(KVcsType))
       
   679 		{ 
       
   680         SetTypeL(KVcalendar);
       
   681         return;
       
   682         }
       
   683 	if(!aExt.CompareC(KTxtType))
       
   684 		{
       
   685 		SetTypeL(KTextPlain);
       
   686 		return;
       
   687 		}
       
   688 	}
       
   689 
       
   690 /** 
       
   691 Gets the object's Name attribute.
       
   692 
       
   693 @return Object's Name attribute or KNullDesC if it has not been set 
       
   694 	
       
   695 @publishedAll
       
   696 @released
       
   697 */
       
   698 EXPORT_C const TDesC& CObexBaseObject::Name()	
       
   699 	{
       
   700 	LOG_LINE
       
   701 	LOG_FUNC
       
   702 
       
   703 	if (iValidHeaders & KObexHdrName)
       
   704 		{
       
   705 		__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
   706 		
       
   707 		//reset the mask so all headers are searched
       
   708 		//NB. SetMask sets the iterator at the start of the headerset
       
   709 		iHeaderSet->SetMask(NULL);
       
   710 
       
   711 		// search for a Name header in the headerset
       
   712 		if (iHeaderSet->Find(TObexInternalHeader::EName, *iObexHeader) == KErrNone)
       
   713 			{
       
   714 			//header is found so return the HV as Unicode
       
   715 			return (iObexHeader->AsUnicode());
       
   716 			}
       
   717 		else
       
   718 			{
       
   719 			return (KNullDesC);
       
   720 			}
       
   721 		}
       
   722 	else
       
   723 		{
       
   724 		return (KNullDesC);
       
   725 		}
       
   726 	}
       
   727 
       
   728 /** 
       
   729 Gets the object's Type attribute.
       
   730 
       
   731 @return Object's Type attribute or KNullDesC8 if it has not been set 
       
   732 	
       
   733 @publishedAll
       
   734 @released
       
   735 */
       
   736 EXPORT_C const TDesC8& CObexBaseObject::Type()
       
   737 	{
       
   738 	LOG_LINE
       
   739 	LOG_FUNC
       
   740 
       
   741 	if (iValidHeaders & KObexHdrType)
       
   742 		{
       
   743 		__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
   744 		
       
   745 		//reset the mask so all headers are searched
       
   746 		//NB. SetMask sets the iterator at the start of the headerset
       
   747 		iHeaderSet->SetMask(NULL);
       
   748 
       
   749 		// search for a Type header in the headerset
       
   750 		if (iHeaderSet->Find(TObexInternalHeader::EType, *iObexHeader) == KErrNone)
       
   751 			{
       
   752 			//header is found so return the HV as ByteSequence
       
   753 			return (iObexHeader->AsByteSeq());
       
   754 			}
       
   755 		else
       
   756 			{
       
   757 			return (KNullDesC8);
       
   758 			}
       
   759 		}
       
   760 	else
       
   761 		{
       
   762 		return (KNullDesC8);
       
   763 		}
       
   764 	}
       
   765 
       
   766 /** 
       
   767 Gets the object's Length attribute.
       
   768 
       
   769 Note this might not match the size of the file (if any) to transfer.
       
   770 
       
   771 @return Object's Length attribute or 0 if it has not been set 
       
   772 	
       
   773 @publishedAll
       
   774 @released
       
   775 */
       
   776 EXPORT_C TUint32 CObexBaseObject::Length()
       
   777 	{
       
   778 	LOG_LINE
       
   779 	LOG_FUNC
       
   780 
       
   781 	if (iValidHeaders & KObexHdrLength)
       
   782 		{
       
   783 		__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
   784 		
       
   785 		//reset the mask so all headers are searched
       
   786 		//NB. SetMask sets the iterator at the start of the headerset
       
   787 		iHeaderSet->SetMask(NULL);
       
   788 
       
   789 		// search for a Length header in the headerset
       
   790 		if (iHeaderSet->Find(TObexInternalHeader::ELength, *iObexHeader) == KErrNone)
       
   791 			{
       
   792 			//header is found so return the HV as FourByte
       
   793 			return (iObexHeader->AsFourByte());
       
   794 			}
       
   795 		else
       
   796 			{
       
   797 			return (0);
       
   798 			}
       
   799 		}
       
   800 	else
       
   801 		{
       
   802 		return (0);
       
   803 		}
       
   804 	}
       
   805 	
       
   806 /**
       
   807 Firstly updates the iHttp list, ensuring that the entries are 
       
   808 the same as those HTTP headers within the header set.
       
   809 (The iHttp list could have contained old headers that were removed from
       
   810 the headerset using the DeleteMasked operation)
       
   811 Returns a pointer to the Http header array or null if no headers defined.
       
   812 @return	A pointer to the Http header array or null if no headers defined 
       
   813 	
       
   814 @publishedAll
       
   815 @released
       
   816 **/
       
   817 EXPORT_C const RPointerArray<HBufC8>* CObexBaseObject::Http() const
       
   818 	{
       
   819 	LOG_LINE
       
   820 	LOG_FUNC
       
   821 
       
   822 	// if there are headers in the iHttp list
       
   823 	if (iHttp && (iHttp->Count()))
       
   824 		{
       
   825 		
       
   826 		TInt httpCount = 0;
       
   827 
       
   828 		__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
   829 		
       
   830 		//reset the mask so all headers are searched
       
   831 		//NB. SetMask sets the iterator at the start of the headerset
       
   832 		iHeaderSet->SetMask(NULL);
       
   833 
       
   834 		TInt err = iHeaderSet->Find(TObexInternalHeader::EHttp, *iObexHeader);
       
   835 		while (err == KErrNone)
       
   836 			{
       
   837 			httpCount++;
       
   838 			err = iHeaderSet->Next();
       
   839 			if (!err)
       
   840 				{
       
   841 		 		err = iHeaderSet->Find(TObexInternalHeader::EHttp, *iObexHeader);
       
   842 		 		}
       
   843 			}	
       
   844 			
       
   845 		// check if number of HTTP in iHttp equals number in header set
       
   846 		// NB. if equal then they must be the same headers due to the way that the
       
   847 		// addition of HTTP headers has been implemented (ie. both AddHttpL and 
       
   848 		// AddHeader for Http, will update the iHTTP list, as well as HeaderSet)
       
   849 		//
       
   850 		if (httpCount != (iHttp->Count()))
       
   851 			{
       
   852 			// reset the header iterator to the start of the headerset
       
   853 			iHeaderSet->First();
       
   854 
       
   855 			TInt arrayIndex = 0;
       
   856 			
       
   857 			// search for an Http header in the headerset
       
   858 		 	err = iHeaderSet->Find(TObexInternalHeader::EHttp, *iObexHeader);
       
   859 
       
   860 			while (err == KErrNone)
       
   861 				{
       
   862 				//delete items from the iHttp list until an HTTP header with the same HV value
       
   863 				//as the HTTP header in the headerset has been located.
       
   864 				while ((iObexHeader->AsByteSeq()) != (((*iHttp)[arrayIndex])->Des()))
       
   865 					{
       
   866 					delete (*iHttp)[arrayIndex];
       
   867 					(*iHttp).Remove(arrayIndex);
       
   868 					}
       
   869 				
       
   870 				arrayIndex++;
       
   871 				
       
   872 				// search for an Http header in the headerset
       
   873 				iHeaderSet->Next();
       
   874 			 	err = iHeaderSet->Find(TObexInternalHeader::EHttp, *iObexHeader);
       
   875 				}
       
   876 
       
   877 			// if the number of HTTP headers in the headerset is different to the iHTTP count
       
   878 			// then there must be some remaining headers at the end of the list, so remove 
       
   879 			// them
       
   880 			while (httpCount < (iHttp->Count()))
       
   881 				{
       
   882 				delete (*iHttp)[arrayIndex];
       
   883 				(*iHttp).Remove(arrayIndex);
       
   884 				}
       
   885 			}
       
   886 
       
   887 		// if there are no elements in the iHttp list, delete the list and return NULL			
       
   888 		if (iHttp->Count() == 0)
       
   889 			{
       
   890 			if (iHttp)
       
   891 				{
       
   892 				iHttp->ResetAndDestroy();
       
   893 				delete iHttp;
       
   894 				iHttp = NULL;
       
   895 				}
       
   896 	
       
   897 			return NULL;
       
   898 			}
       
   899 		else
       
   900 			{
       
   901 			//return the iHttp pointer
       
   902 			return iHttp;
       
   903 			}
       
   904 		}
       
   905 	else //iHttp && iHttp->Count
       
   906 		{
       
   907 		return NULL;
       
   908 		}
       
   909 	}
       
   910 	
       
   911 /**
       
   912 Take time string specified in ISO8601 format and convert to a TTime
       
   913 @param aTime Time descriptor in ISO8601 format
       
   914 @param aResult Object to place resultant local time. Set to 0 if conversion fails.
       
   915 */
       
   916 void ParseISO8601Time(const TDesC& aTimeDes, TTime& aResult)
       
   917 	{
       
   918 	LOG_STATIC_FUNC_ENTRY
       
   919 	FLOG(_L8("Parsing ISO 8601 format time"));
       
   920 	
       
   921 	TInt yr, mn, dy, hr, mi, sc;
       
   922 	TLex lex(aTimeDes);
       
   923 	aResult = 0; // return TTime(0) by default
       
   924  
       
   925 	// Get date components
       
   926 	TUint num;
       
   927 	if (lex.Val(num) != KErrNone)
       
   928 		{
       
   929 		FLOG(_L8("Date not found"));
       
   930 		return;
       
   931 		}
       
   932 
       
   933 	dy = num % 100;
       
   934 	num /= 100;
       
   935 	mn = num % 100;
       
   936 	num /= 100;
       
   937 	yr = num;
       
   938 
       
   939 	if (lex.Get() != 'T')
       
   940 		{
       
   941 		FLOG(_L8("Char 'T' not found"));
       
   942 		return;
       
   943 		}
       
   944 	
       
   945 	// Get time components
       
   946 	if (lex.Val(num) != KErrNone)
       
   947 		{
       
   948 		FLOG(_L8("Time not found"));
       
   949 		return;
       
   950 		}
       
   951 	sc = num % 100;
       
   952 	num /= 100;
       
   953 	mi = num % 100;
       
   954 	num /= 100;
       
   955 	hr = num;
       
   956  
       
   957 	// Convert components into a TTime
       
   958 	TDateTime dt;
       
   959 	if (dt.Set(yr,TMonth(mn-1),(dy-1),hr,mi,sc,0) != KErrNone) // day and month are zero based in TDateTime::Set
       
   960 		{
       
   961 		FLOG(_L8("Failed to convert time"));
       
   962 		return;
       
   963 		}
       
   964 	aResult = dt;
       
   965 
       
   966 	// If time is in UTC, convert to local time
       
   967 	if (lex.Get() == 'Z')
       
   968 		{
       
   969 		aResult += User::UTCOffset(); // includes any daylight saving correction
       
   970 		}
       
   971 	}
       
   972 
       
   973 /**
       
   974 Returns the time attribute of the object in local time.
       
   975 Returns TTime (0) if no valid time has been set.
       
   976 
       
   977 @return Object's Time attribute in local time or TTime(0) if it has not been set 
       
   978 	
       
   979 @publishedAll
       
   980 @released
       
   981 **/
       
   982 EXPORT_C const TTime CObexBaseObject::Time()
       
   983 	{
       
   984 	LOG_LINE
       
   985 	LOG_FUNC
       
   986 
       
   987 	TTime newTime = TTime(0);
       
   988 	
       
   989 	if (iValidHeaders & KObexHdrTime)
       
   990 		{
       
   991 		__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
   992 		
       
   993 		//reset the mask so all headers are searched
       
   994 		//NB. SetMask sets the iterator at the start of the headerset
       
   995 		iHeaderSet->SetMask(NULL);
       
   996 
       
   997 		if (iHeaderSet->Find(TObexInternalHeader::ETime, *iObexHeader) == KErrNone)
       
   998 			{
       
   999 			TBuf16<16> localbuf;
       
  1000 			localbuf.Copy(iObexHeader->AsByteSeq());
       
  1001 
       
  1002 			ParseISO8601Time(localbuf, newTime);
       
  1003 			}
       
  1004 		}
       
  1005 	return newTime;
       
  1006 	}
       
  1007 
       
  1008 /** 
       
  1009 Gets the object's Description attribute.
       
  1010 
       
  1011 @return Object's Name attribute or KNullDesC if it has not been set 
       
  1012 	
       
  1013 @publishedAll
       
  1014 @released
       
  1015 */
       
  1016 EXPORT_C const TDesC& CObexBaseObject::Description()
       
  1017 	{
       
  1018 	LOG_LINE
       
  1019 	LOG_FUNC
       
  1020 
       
  1021 	if (iValidHeaders & KObexHdrDescription)
       
  1022 		{
       
  1023 		__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
  1024 		
       
  1025 		//reset the mask so all headers are searched
       
  1026 		//NB. SetMask sets the iterator at the start of the headerset
       
  1027 		iHeaderSet->SetMask(NULL);
       
  1028 
       
  1029 		// search for a Description header in the headerset
       
  1030 		if (iHeaderSet->Find(TObexInternalHeader::EDescription, *iObexHeader) == KErrNone)
       
  1031 			{
       
  1032 			//header is found so return the HV as Unicode
       
  1033 			return (iObexHeader->AsUnicode());
       
  1034 			}
       
  1035 		else
       
  1036 			{
       
  1037 			return (KNullDesC);
       
  1038 			}
       
  1039 		}
       
  1040 	else
       
  1041 		{
       
  1042 		return (KNullDesC);
       
  1043 		}
       
  1044 	}
       
  1045 
       
  1046 /**	
       
  1047 Gets the object's Application Parameters attribute
       
  1048 
       
  1049 This function does not parse the Application Parameters attribute into the 
       
  1050 expected Tag-Length-Value format.
       
  1051 
       
  1052 @return Object's Application Parameters attribute, or KNullDesC8 if none has been set 
       
  1053 	
       
  1054 @publishedAll
       
  1055 @released
       
  1056 */
       
  1057 EXPORT_C const TDesC8& CObexBaseObject::AppParam() const
       
  1058 	{
       
  1059 	LOG_LINE
       
  1060 	LOG_FUNC
       
  1061 
       
  1062 	if (iValidHeaders & KObexHdrAppParam)
       
  1063 		{
       
  1064 		__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
  1065 		
       
  1066 		//reset the mask so all headers are searched
       
  1067 		//NB. SetMask sets the iterator at the start of the headerset
       
  1068 		iHeaderSet->SetMask(NULL);
       
  1069 
       
  1070 		// search for a AppParam header in the headerset
       
  1071 		if (iHeaderSet->Find(TObexInternalHeader::EAppParam, *iObexHeader) == KErrNone)
       
  1072 			{
       
  1073 			//header is found so return the HV as ByteSeq
       
  1074 			return (iObexHeader->AsByteSeq());
       
  1075 			}
       
  1076 		else
       
  1077 			{
       
  1078 			return (KNullDesC8);
       
  1079 			}
       
  1080 		}
       
  1081 	else
       
  1082 		{
       
  1083 		return (KNullDesC8);
       
  1084 		}
       
  1085 	}
       
  1086 
       
  1087 /** 
       
  1088 Gets the object's Target attribute.
       
  1089 
       
  1090 @return Object's Target attribute or KNullDesC8 if it has not been set 
       
  1091 	
       
  1092 @publishedAll
       
  1093 @released
       
  1094 */
       
  1095 EXPORT_C const TDesC8& CObexBaseObject::Target()
       
  1096 	{
       
  1097 	LOG_LINE
       
  1098 	LOG_FUNC
       
  1099 
       
  1100 	if (iValidHeaders & KObexHdrTarget)
       
  1101 		{
       
  1102 		__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
  1103 		
       
  1104 		//reset the mask so all headers are searched
       
  1105 		//NB. SetMask sets the iterator at the start of the headerset
       
  1106 		iHeaderSet->SetMask(NULL);
       
  1107 
       
  1108 		// search for a Target header in the headerset
       
  1109 		if (iHeaderSet->Find(TObexInternalHeader::ETarget, *iObexHeader) == KErrNone)
       
  1110 			{
       
  1111 			//header is found so return the HV as ByteSeq
       
  1112 			return (iObexHeader->AsByteSeq());
       
  1113 			}
       
  1114 		else
       
  1115 			{
       
  1116 			return (KNullDesC8);
       
  1117 			}
       
  1118 		}
       
  1119 	else
       
  1120 		{
       
  1121 		return (KNullDesC8);
       
  1122 		}
       
  1123 	}
       
  1124 
       
  1125 /**
       
  1126 @publishedAll
       
  1127 @released
       
  1128 @return A const reference to the HeaderSet object used by this object.
       
  1129 @see CObexHeaderSet
       
  1130 */
       
  1131 EXPORT_C const CObexHeaderSet& CObexBaseObject::HeaderSet() const
       
  1132 	{
       
  1133 	LOG_LINE
       
  1134 	LOG_FUNC
       
  1135 
       
  1136 	return *iHeaderSet;
       
  1137 	}
       
  1138 	
       
  1139 /**
       
  1140 @publishedAll
       
  1141 @released
       
  1142 @return A reference to the HeaderSet object used by this object.
       
  1143 @see CObexHeaderSet
       
  1144 */
       
  1145 EXPORT_C CObexHeaderSet& CObexBaseObject::HeaderSet()
       
  1146 	{
       
  1147 	LOG_LINE
       
  1148 	LOG_FUNC
       
  1149 
       
  1150 	return *iHeaderSet;
       
  1151 	}
       
  1152 
       
  1153 /**
       
  1154 Prepare the object for sending. Each packet sent will contain aOpcode.
       
  1155 	
       
  1156 @param aOpcode
       
  1157 @return KErrNone
       
  1158 @internalComponent
       
  1159 */
       
  1160 TInt CObexBaseObject::InitSend(TObexOpcode aOpcode)
       
  1161 	{
       
  1162 	FLOG(_L("CObexBaseObject::InitSend"));
       
  1163 	
       
  1164 	iSendHeaders = 0;
       
  1165 	iSendBytes = 0;
       
  1166 	iSendOpcode = aOpcode;
       
  1167 	iSendProgress = EContinue;
       
  1168 
       
  1169 	return KErrNone;
       
  1170 	}
       
  1171 
       
  1172 /**
       
  1173 Fill up the Connect command with the appropriate headers.
       
  1174 
       
  1175 @param aPacket The packet to be filled
       
  1176 @internalComponent
       
  1177 */
       
  1178 void CObexBaseObject::PrepareConnectionHeader(CObexPacket &aPacket)
       
  1179 	{
       
  1180 	FLOG(_L("CObexBaseObject::PrepareConnectionHeader\r\n"));
       
  1181 	TObexInternalHeader header;
       
  1182 	
       
  1183 	TObexHeaderMask remaininghdr = static_cast<TObexHeaderMask>(iValidHeaders & iHeaderMask);
       
  1184 	if(remaininghdr)
       
  1185 		{// ...there are some valid, unsent headers left to send.
       
  1186 		//the Target header should be sent first
       
  1187 		if(remaininghdr & KObexHdrTarget) 
       
  1188 			{
       
  1189 			FLOG(_L("PrepareConnectionHeader - Preparing Target Header\r\n"));
       
  1190 
       
  1191 			if ( Target() != KNullDesC8 )
       
  1192 				{
       
  1193 				header.Set(TObexInternalHeader::ETarget, (const_cast<TUint8*>(Target().Ptr())), Target().Size());
       
  1194 
       
  1195 				if(aPacket.InsertData(header)) 
       
  1196 					{
       
  1197 					iSendHeaders |= KObexHdrTarget;
       
  1198 					iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1199 
       
  1200 					}
       
  1201 				}
       
  1202 			}
       
  1203 		}
       
  1204 	}
       
  1205 
       
  1206 /**
       
  1207 Fill up aPacket with whatever is left to be sent of the object.
       
  1208 Trys to get attribute headers out asap,
       
  1209 and tacks as much of the data part of the object onto the end of each 
       
  1210 packet as will fit. Returned value goes to EComplete on the call *after* 
       
  1211 the final packet has been written(i.e. indicates nothing left to do).
       
  1212 
       
  1213 @param aPacket The packet to be filled
       
  1214 @return Progress in writing out the object
       
  1215 @internalComponent
       
  1216 */
       
  1217 CObexBaseObject::TProgress CObexBaseObject::PrepareNextSendPacket(CObexPacket &aPacket)
       
  1218 	{
       
  1219 	FLOG(_L("CObexBaseObject::PrepareNextSendPacket\r\n"));
       
  1220 	
       
  1221 	// iHeaderSet is often dereferenced in this method. So it worth to check it
       
  1222 	// at the beginning
       
  1223 	
       
  1224 	__ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer));
       
  1225 	
       
  1226 	if(iSendProgress == ELastPacket)
       
  1227 		{
       
  1228 		/*
       
  1229 		If the state was 'ELastPacket' as a result of the 
       
  1230 		last call to this method, then the last packet will
       
  1231 		now have been sent!
       
  1232 		*/
       
  1233 		iSendProgress = EComplete;
       
  1234 		}
       
  1235 		
       
  1236 	if(iSendProgress != EContinue)
       
  1237 		{
       
  1238 		FLOG(_L("PrepareNextSendPacket - immediate exit\r\n"));
       
  1239 		return(iSendProgress);
       
  1240 		}
       
  1241 		
       
  1242 	TObexInternalHeader header;
       
  1243 	aPacket.Init(iSendOpcode); 
       
  1244 	TInt startspace = aPacket.RemainingInsertSpace();
       
  1245 
       
  1246 	TObexHeaderMask remaininghdr = static_cast<TObexHeaderMask>(~iSendHeaders & iValidHeaders & iHeaderMask);
       
  1247 	TBool suppressDataHeader = EFalse;
       
  1248 	TBool firstHeader = ETrue;
       
  1249 	if(remaininghdr)
       
  1250 		{// ...there are some valid, unsent headers left to send.
       
  1251 		if(remaininghdr & KObexHdrTarget) 
       
  1252 			{
       
  1253 			FLOG(_L("PrepareConnectionHeader - Preparing Target Header\r\n"));
       
  1254 
       
  1255 			header.Set(TObexInternalHeader::ETarget, (const_cast<TUint8*> (Target().Ptr())), Target().Size());
       
  1256 			if(aPacket.InsertData(header)) 
       
  1257 				{
       
  1258 				iSendHeaders |= KObexHdrTarget;
       
  1259 				iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1260 				//set that a header has been added to this current packet
       
  1261 				firstHeader = EFalse;
       
  1262 				}
       
  1263 			}
       
  1264 			
       
  1265 		if (remaininghdr & KObexHdrConnectionID)
       
  1266 			{
       
  1267 			FLOG(_L("PrepareNextSendPacket - preparing EConnectionID header\r\n"));
       
  1268 
       
  1269 			TUint32 connID = ConnectionID();
       
  1270 			if ( connID != KConnIDInvalid )
       
  1271 				{
       
  1272 
       
  1273 				TUint32 newConnectionID = connID;
       
  1274               	header.Set(TObexInternalHeader::EConnectionID, newConnectionID);
       
  1275               	
       
  1276 				if(aPacket.InsertData(header)) 
       
  1277 					{
       
  1278 					iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1279 
       
  1280 					iSendHeaders |= KObexHdrConnectionID;
       
  1281 					//set that a header has been added to this current packet
       
  1282 					firstHeader = EFalse;
       
  1283 					}
       
  1284 				}
       
  1285 			else
       
  1286 				{
       
  1287 				iValidHeaders &= ~KObexHdrConnectionID;
       
  1288 				}
       
  1289 			}
       
  1290 
       
  1291 		if(remaininghdr & KObexHdrName) 
       
  1292 			{ 
       
  1293 			FLOG(_L("PrepareNextSendPacket - preparing EName header\r\n"));
       
  1294 
       
  1295 			header.Set(TObexInternalHeader::EName, Name());
       
  1296 			if(aPacket.InsertData(header)) 
       
  1297 				{
       
  1298 				iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1299 
       
  1300 				iSendHeaders |= KObexHdrName;
       
  1301 				//set that a header has been added to this current packet
       
  1302 				firstHeader = EFalse;
       
  1303 				}
       
  1304 			}
       
  1305 
       
  1306 		if(remaininghdr & KObexHdrLength) 
       
  1307 			{ 
       
  1308 			FLOG(_L("PrepareNextSendPacket - preparing ELength header\r\n"));
       
  1309 
       
  1310 			header.Set(TObexInternalHeader::ELength, Length()); 
       
  1311 			if(aPacket.InsertData(header)) 
       
  1312 				{
       
  1313 				iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1314 
       
  1315 				iSendHeaders |= KObexHdrLength;
       
  1316 				//set that a header has been added to this current packet
       
  1317 				firstHeader = EFalse;
       
  1318 				}
       
  1319 			}
       
  1320 		if(remaininghdr & KObexHdrType) 
       
  1321 			{ 
       
  1322 			FLOG(_L("PrepareNextSendPacket - preparing EType header\r\n"));
       
  1323 
       
  1324 			header.Set(TObexInternalHeader::EType, (const_cast<TUint8*> (Type().Ptr())), Type().Size());
       
  1325 					
       
  1326 			if(aPacket.InsertData(header)) 
       
  1327 				{
       
  1328 				iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1329 
       
  1330 				iSendHeaders |= KObexHdrType;
       
  1331 				//set that a header has been added to this current packet
       
  1332 				firstHeader = EFalse;
       
  1333 				}
       
  1334 			}
       
  1335 			
       
  1336 		if(remaininghdr & KObexHdrDescription) 
       
  1337 			{ 
       
  1338 			FLOG(_L("PrepareNextSendPacket - preparing EDescription header\r\n"));
       
  1339 
       
  1340 			header.Set(TObexInternalHeader::EDescription, Description()); 
       
  1341 			if(aPacket.InsertData(header)) 
       
  1342 				{
       
  1343 				iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1344 
       
  1345 				iSendHeaders |= KObexHdrDescription;
       
  1346 				//set that a header has been added to this current packet
       
  1347 				firstHeader = EFalse;
       
  1348 				}
       
  1349 			}
       
  1350 		if(remaininghdr & KObexHdrCount) 
       
  1351 			{
       
  1352 			FLOG(_L("PrepareNextSendPacket - preparing ECount header\r\n"));
       
  1353 
       
  1354 			if (iValidHeaders & KObexHdrCount)
       
  1355 				{
       
  1356 				//reset the mask so all headers are searched
       
  1357 				//NB. SetMask sets the iterator at the start of the headerset
       
  1358 				iHeaderSet->SetMask(NULL);
       
  1359 
       
  1360 				if (iHeaderSet->Find(TObexInternalHeader::ECount, *iObexHeader) == KErrNone)
       
  1361 					{
       
  1362 
       
  1363 					TUint32 newCount = iObexHeader->AsFourByte();
       
  1364 					header.Set(TObexInternalHeader::ECount, newCount);
       
  1365 						
       
  1366 					if(aPacket.InsertData(header)) 
       
  1367 						{
       
  1368 						iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1369 
       
  1370 						iSendHeaders |= KObexHdrCount;
       
  1371 						//set that a header has been added to this current packet
       
  1372 						firstHeader = EFalse;
       
  1373 						}
       
  1374 					}
       
  1375 				else
       
  1376 					{
       
  1377 					iValidHeaders &= ~KObexHdrCount;
       
  1378 					}
       
  1379 				}
       
  1380 			else
       
  1381 				{
       
  1382 				iValidHeaders &= ~KObexHdrCount;
       
  1383 				}
       
  1384 			}
       
  1385 		if (remaininghdr & KObexHdrAppParam)
       
  1386 			{
       
  1387 			FLOG(_L("PrepareNextSendPacket - preparing EAppParam header\r\n"));
       
  1388 
       
  1389 			header.Set(TObexInternalHeader::EAppParam, (const_cast<TUint8*> (AppParam().Ptr())), AppParam().Size());
       
  1390 
       
  1391 			if (aPacket.InsertData(header))
       
  1392 				{
       
  1393 				iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1394 
       
  1395 				iSendHeaders |= KObexHdrAppParam;
       
  1396 				//set that a header has been added to this current packet
       
  1397 				firstHeader = EFalse;
       
  1398 				}
       
  1399 			}
       
  1400 		
       
  1401 		if (remaininghdr & KObexHdrHttp)
       
  1402 			{
       
  1403 			//no need to check iValidHeaders as if it is false then remaininghdr would be too.
       
  1404 
       
  1405 			//reset the mask so all headers are searched
       
  1406 			//NB. SetMask sets the iterator at the start of the headerset
       
  1407 			iHeaderSet->SetMask(NULL);
       
  1408 
       
  1409 			TBool headerFound = EFalse;
       
  1410 			TUint headerFoundCount = 0;
       
  1411 			TUint headerHandledCount = 0;
       
  1412 			
       
  1413 			TInt err = iHeaderSet->Find(TObexInternalHeader::EHttp, *iObexHeader);
       
  1414 
       
  1415 			while (err == KErrNone)
       
  1416 				{
       
  1417 				headerFoundCount++;
       
  1418 				
       
  1419 				if ( (!(iObexHeader->Attributes() & CObexHeader::ESent)) &&
       
  1420 					 (!(iObexHeader->Attributes() & CObexHeader::ESuppressed)) )
       
  1421 					{
       
  1422 					//Unsent and Unsuppressed Http header had been found
       
  1423 					headerFound = ETrue;
       
  1424 
       
  1425 					header.Set(TObexInternalHeader::EHttp, (const_cast<TUint8*> ((iObexHeader->AsByteSeq()).Ptr())), (iObexHeader->AsByteSeq()).Size());
       
  1426 				
       
  1427 					if(aPacket.InsertData(header)) 
       
  1428 						{
       
  1429 						iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1430 						headerHandledCount++;
       
  1431 		
       
  1432 						//set that a header has been added to this current packet
       
  1433 						firstHeader = EFalse;
       
  1434 						}
       
  1435 					else if (firstHeader)
       
  1436 						{
       
  1437 						// Had problems inserting the first HTTP header, Set it to suppressed.
       
  1438 						// (this is also the first header in the packet, so we had the full
       
  1439 						// packet size available)
       
  1440 						iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESuppressed));
       
  1441 						headerHandledCount++;
       
  1442 						}
       
  1443 					}
       
  1444 				else
       
  1445 					{
       
  1446 					//Header has previously been sent/suppressed
       
  1447 					headerHandledCount++;
       
  1448 					}
       
  1449 
       
  1450 				iHeaderSet->Next();
       
  1451 				err = iHeaderSet->Find(TObexInternalHeader::EHttp, *iObexHeader);
       
  1452 				}
       
  1453 		
       
  1454 			if (headerFoundCount == headerHandledCount)
       
  1455 				{
       
  1456 				//All HTTP headers have been sent (or suppressed)
       
  1457 				iSendHeaders |= KObexHdrHttp;
       
  1458 				}
       
  1459 			
       
  1460 			// an unsent http header cannot be found in headerset so set flag to invalid
       
  1461 			if (headerFound == EFalse)
       
  1462 				{
       
  1463 				iValidHeaders &= ~KObexHdrHttp;
       
  1464 				}
       
  1465 			}
       
  1466 
       
  1467 		if(remaininghdr & KObexHdrCreatorID) 
       
  1468 			{
       
  1469 			FLOG(_L("PrepareNextSendPacket - preparing ECreatorID header\r\n"));
       
  1470 
       
  1471 			if (iValidHeaders & KObexHdrCreatorID)
       
  1472 				{
       
  1473 				//reset the mask so all headers are searched
       
  1474 				//NB. SetMask sets the iterator at the start of the headerset
       
  1475 				iHeaderSet->SetMask(NULL);
       
  1476 
       
  1477 				if (iHeaderSet->Find(TObexInternalHeader::ECreatorID, *iObexHeader) == KErrNone)
       
  1478 					{
       
  1479 					header.Set(TObexInternalHeader::ECreatorID, iObexHeader->AsFourByte());
       
  1480 					if(aPacket.InsertData(header)) 
       
  1481 						{
       
  1482 						iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1483 						iSendHeaders |= KObexHdrCreatorID;
       
  1484 						//set that a header has been added to this current packet
       
  1485 						firstHeader = EFalse;
       
  1486 						}
       
  1487 					}
       
  1488 				else
       
  1489 					{
       
  1490 					iValidHeaders &= ~KObexHdrCreatorID;
       
  1491 					}
       
  1492 				}
       
  1493 			else
       
  1494 				{
       
  1495 				iValidHeaders &= ~KObexHdrCreatorID;
       
  1496 				}
       
  1497 			}
       
  1498 
       
  1499 		if(remaininghdr & KObexHdrWanUUID) 
       
  1500 			{
       
  1501 			FLOG(_L("PrepareNextSendPacket - preparing EWanUUID header\r\n"));
       
  1502 			if (iValidHeaders & KObexHdrWanUUID)
       
  1503 				{
       
  1504 				//reset the mask so all headers are searched
       
  1505 				//NB. SetMask sets the iterator at the start of the headerset
       
  1506 				iHeaderSet->SetMask(NULL);
       
  1507 
       
  1508 				if (iHeaderSet->Find(TObexInternalHeader::EWanUUID, *iObexHeader) == KErrNone)
       
  1509 					{
       
  1510 					header.Set(TObexInternalHeader::EWanUUID, (const_cast<TUint8*> ((iObexHeader->AsByteSeq()).Ptr())), (iObexHeader->AsByteSeq()).Size());
       
  1511 					if(aPacket.InsertData(header)) 
       
  1512 						{
       
  1513 						iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1514 						iSendHeaders |= KObexHdrWanUUID;
       
  1515 						//set that a header has been added to this current packet
       
  1516 						firstHeader = EFalse;
       
  1517 						}
       
  1518 					}
       
  1519 				else
       
  1520 					{
       
  1521 					iValidHeaders &= ~KObexHdrWanUUID;
       
  1522 					}
       
  1523 				}
       
  1524 			else
       
  1525 				{
       
  1526 				iValidHeaders &= ~KObexHdrWanUUID;
       
  1527 				}
       
  1528 			}
       
  1529 
       
  1530 		if(remaininghdr & KObexHdrObjectClass) 
       
  1531 			{
       
  1532 			FLOG(_L("PrepareNextSendPacket - preparing EObjectClass header\r\n"));
       
  1533 			if (iValidHeaders & KObexHdrObjectClass)
       
  1534 				{
       
  1535 				//reset the mask so all headers are searched
       
  1536 				//NB. SetMask sets the iterator at the start of the headerset
       
  1537 				iHeaderSet->SetMask(NULL);
       
  1538 
       
  1539 				if (iHeaderSet->Find(TObexInternalHeader::EObjectClass, *iObexHeader) == KErrNone)
       
  1540 					{
       
  1541 					header.Set(TObexInternalHeader::EObjectClass, (const_cast<TUint8*> ((iObexHeader->AsByteSeq()).Ptr())), (iObexHeader->AsByteSeq()).Size());
       
  1542 					if(aPacket.InsertData(header)) 
       
  1543 						{
       
  1544 						iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1545 
       
  1546 						iSendHeaders |= KObexHdrObjectClass;
       
  1547 						//set that a header has been added to this current packet
       
  1548 						firstHeader = EFalse;
       
  1549 						}
       
  1550 					}
       
  1551 				else
       
  1552 					{
       
  1553 					iValidHeaders &= ~KObexHdrObjectClass;
       
  1554 					}
       
  1555 				}
       
  1556 			else
       
  1557 				{
       
  1558 				iValidHeaders &= ~KObexHdrObjectClass;
       
  1559 				}				
       
  1560 			}
       
  1561 		if (remaininghdr & KObexHdrUserDefined)
       
  1562 			{
       
  1563 			TBool headerFound = EFalse;
       
  1564 			TUint headerFoundCount = 0;
       
  1565 			TUint headerSentCount = 0;
       
  1566 			TInt err = 0;
       
  1567 			
       
  1568 			//reset the mask so all headers are searched
       
  1569 			//NB. SetMask sets the iterator at the start of the headerset
       
  1570 			iHeaderSet->SetMask(NULL);
       
  1571 			
       
  1572 			for (TUint8 headerTypeIndex = TObexInternalHeader::EUnicode; 
       
  1573 							headerTypeIndex <= TObexInternalHeader::E4Byte;)
       
  1574 				// NB. iterative step not included in this for loop, this is done at the end 
       
  1575 				//of the for loop: moves headerTypeIndex to the next type
       
  1576 				{
       
  1577 									
       
  1578 				for (TUint8 headerNameIndex = KObexUserDefinedHdrAddrMin; 
       
  1579 							headerNameIndex <= KObexUserDefinedHdrAddrMax; headerNameIndex++)
       
  1580 					{
       
  1581 					TUint8 localHI = static_cast<TUint8>(headerTypeIndex | headerNameIndex);
       
  1582 			
       
  1583 					iHeaderSet->First();
       
  1584 						
       
  1585 					err = iHeaderSet->Find(localHI, *iObexHeader);
       
  1586 
       
  1587 					if (err == KErrNone)
       
  1588 						{
       
  1589 						headerFoundCount++;
       
  1590 							
       
  1591 						if ((iObexHeader->Attributes() & CObexHeader::ESent) == 0)
       
  1592 							{
       
  1593 							headerFound = ETrue;
       
  1594 
       
  1595 							switch (headerTypeIndex)
       
  1596 								{
       
  1597 								case (TObexInternalHeader::EUnicode) : 
       
  1598 								{
       
  1599 								header.Set(localHI, iObexHeader->AsUnicode());
       
  1600 								if(aPacket.InsertData(header)) 
       
  1601 									{
       
  1602 									iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1603 
       
  1604 									headerSentCount++;
       
  1605 									//set that a header has been added to this current packet
       
  1606 									firstHeader = EFalse;
       
  1607 									}
       
  1608 
       
  1609 								break;
       
  1610 								}
       
  1611 								case (TObexInternalHeader::EByteSeq) : 
       
  1612 								{
       
  1613 								header.Set(localHI, (const_cast<TUint8*> ((iObexHeader->AsByteSeq()).Ptr())), (iObexHeader->AsByteSeq()).Size());
       
  1614 		
       
  1615 								if(aPacket.InsertData(header)) 
       
  1616 									{
       
  1617 									iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1618 
       
  1619 									headerSentCount++;
       
  1620 									//set that a header has been added to this current packet
       
  1621 									firstHeader = EFalse;
       
  1622 									}
       
  1623 								break;
       
  1624 								}
       
  1625 								case (TObexInternalHeader::E1Byte) : 
       
  1626 								{
       
  1627 								header.Set(localHI, iObexHeader->AsByte());
       
  1628 								if(aPacket.InsertData(header)) 
       
  1629 									{
       
  1630 									iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1631 
       
  1632 									headerSentCount++;
       
  1633 									//set that a header has been added to this current packet
       
  1634 									firstHeader = EFalse;
       
  1635 									}
       
  1636 								break;
       
  1637 								}
       
  1638 								case (TObexInternalHeader::E4Byte) : 
       
  1639 								{
       
  1640 								header.Set(localHI, iObexHeader->AsFourByte());
       
  1641 								if(aPacket.InsertData(header)) 
       
  1642 									{
       
  1643 									iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1644 
       
  1645 									headerSentCount++;
       
  1646 									//set that a header has been added to this current packet
       
  1647 									firstHeader = EFalse;
       
  1648 									}
       
  1649 								break;
       
  1650 								}
       
  1651 								default  : 
       
  1652 								{
       
  1653 								break;
       
  1654 								}
       
  1655 								}
       
  1656 							}
       
  1657 						else	
       
  1658 							{	
       
  1659 							//header has been previously sent.
       
  1660 							headerSentCount++;
       
  1661 							}
       
  1662 						}// header not found in headerset	
       
  1663 
       
  1664 					} //for loop: user defined header 'name' addresses
       
  1665 						
       
  1666 	 			// set the header type to the next
       
  1667 	 			//
       
  1668 				switch (headerTypeIndex)
       
  1669 					{
       
  1670 					case (TObexInternalHeader::EUnicode) :
       
  1671 						{
       
  1672 						headerTypeIndex = TObexInternalHeader::EByteSeq;
       
  1673 						break;	
       
  1674 						}
       
  1675 					case (TObexInternalHeader::EByteSeq) :
       
  1676 						{
       
  1677 						headerTypeIndex = TObexInternalHeader::E1Byte;
       
  1678 						break;
       
  1679 						}
       
  1680 					case (TObexInternalHeader::E1Byte) :
       
  1681 						{
       
  1682 						headerTypeIndex = TObexInternalHeader::E4Byte;
       
  1683 						break;
       
  1684 						}
       
  1685 					case (TObexInternalHeader::E4Byte) :
       
  1686 						{
       
  1687 						headerTypeIndex++; // incrementing this past E4Byte will cause for loop to exit
       
  1688 						break;
       
  1689 						}
       
  1690 					default : {break;}
       
  1691 						}
       
  1692 				}//for loop: user defined header 'type' addresses
       
  1693 		
       
  1694 			if (headerFoundCount == headerSentCount)
       
  1695 				{
       
  1696 				//All User defined headers have been sent
       
  1697 				iSendHeaders |= KObexHdrUserDefined;
       
  1698 				}
       
  1699 					
       
  1700 			// an unsent user defined header cannot be found in headerset so set flag to invalid
       
  1701 			if (headerFound == EFalse)
       
  1702 				{
       
  1703 				iValidHeaders &= ~KObexHdrUserDefined;
       
  1704 				}
       
  1705 			}
       
  1706 
       
  1707 		if(remaininghdr & KObexHdrTime)
       
  1708 			{// Must be last, due to Windows 2000 parse bug (see defect v3 EDNJKIN-4N4G7K)
       
  1709 			if (iValidHeaders & KObexHdrTime)
       
  1710 				{
       
  1711 				FLOG(_L("PrepareNextSendPacket - preparing ETime header\r\n"));
       
  1712 				//reset the mask so all headers are searched
       
  1713 				//NB. SetMask sets the iterator at the start of the headerset
       
  1714 				iHeaderSet->SetMask(NULL);
       
  1715 
       
  1716 				if (iHeaderSet->Find(TObexInternalHeader::ETime, *iObexHeader) == KErrNone)
       
  1717 					{
       
  1718 					header.Set(TObexInternalHeader::ETime, (const_cast<TUint8*> ((iObexHeader->AsByteSeq()).Ptr())), (iObexHeader->AsByteSeq()).Size());
       
  1719 					if(aPacket.InsertData(header)) 
       
  1720 						{
       
  1721 						//set that a header has been added to this current packet
       
  1722 						iSendHeaders |= KObexHdrTime;
       
  1723 						iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1724 
       
  1725 						suppressDataHeader = ETrue; // Win2000 Bug work-aroung
       
  1726 						firstHeader = EFalse;
       
  1727 						}
       
  1728 					}
       
  1729 				else
       
  1730 					{
       
  1731 					iValidHeaders &= ~KObexHdrTime;
       
  1732 					}
       
  1733 				}
       
  1734 			else
       
  1735 				{
       
  1736 				iValidHeaders &= ~KObexHdrTime;
       
  1737 				}
       
  1738 			}
       
  1739 		
       
  1740 		remaininghdr = STATIC_CAST(TObexHeaderMask, ~iSendHeaders & iValidHeaders & iHeaderMask);
       
  1741 		
       
  1742 		// Only add EoB if there is no other remaining headers
       
  1743 		if (remaininghdr == KObexHdrEndOfBody)
       
  1744 			{
       
  1745 			//EoB can only be added in Empty objects.
       
  1746 			__ASSERT_ALWAYS(DataSize() == 0, IrOBEXUtil::Panic(EAddingInvalidEoBHeader));
       
  1747 			header.SetHI(TObexInternalHeader::EEndOfBody);
       
  1748 				
       
  1749 			if(aPacket.InsertData(header)) 
       
  1750 				{
       
  1751 				iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent));
       
  1752 
       
  1753 				iSendHeaders |= KObexHdrEndOfBody;
       
  1754 				//set that a header has been added to this current packet
       
  1755 				firstHeader = EFalse;
       
  1756 				}
       
  1757 			else if(aPacket.RemainingInsertSpace() != startspace) //something has been added
       
  1758 				{
       
  1759 				//There is no enough space for EOB this round, try again next time
       
  1760 				return EContinue;			
       
  1761 				}
       
  1762 			//else if nothing has been added, EError will be returned
       
  1763 			remaininghdr = STATIC_CAST(TObexHeaderMask, ~iSendHeaders & iValidHeaders & iHeaderMask); 
       
  1764 			}
       
  1765 		}
       
  1766 	
       
  1767 	TInt dataspace = aPacket.RemainingInsertSpace() - KObexHeaderHILongSize;
       
  1768 	TInt remainingdata = DataSize() - iSendBytes;
       
  1769 	if(dataspace > 0 && remainingdata > 0 && !suppressDataHeader)
       
  1770 		{// ...there's some room for data and we haven't sent it all, and we're allowed to add some
       
  1771 		FLOG(_L("PrepareNextSendPacket - preparing some additional data\r\n"));
       
  1772 		TPtr8 bufptr(NULL, 0);
       
  1773 		if(remainingdata <= dataspace)
       
  1774 			{
       
  1775 			header.SetDeferred(TObexInternalHeader::EEndOfBody, &bufptr, remainingdata, remainingdata);
       
  1776 			}
       
  1777 		else
       
  1778 			{
       
  1779 			header.SetDeferred(TObexInternalHeader::EBody, &bufptr, 1, remainingdata - 1);
       
  1780 			}
       
  1781 		if(!aPacket.InsertData(header))
       
  1782 			{
       
  1783 			return(iSendProgress = EError);
       
  1784 			}
       
  1785 		else
       
  1786 			{// Data header inserted, now load it up with data...
       
  1787 			GetData(iSendBytes, bufptr);
       
  1788 			if(bufptr.Length() < bufptr.MaxLength())
       
  1789 				return(iSendProgress = EError);
       
  1790 			iSendBytes += bufptr.Length();
       
  1791 			remainingdata -= bufptr.Length();
       
  1792 			}
       
  1793 		}
       
  1794 
       
  1795 	if(!(remaininghdr || remainingdata > 0))
       
  1796 		{// Check whether all(valid) headers and data will have been sent
       
  1797 		iSendProgress = ELastPacket;
       
  1798 	
       
  1799 		FLOG(_L("PrepareNextSendPacket - All headers packaged setting Final Bit\r\n"));
       
  1800 		aPacket.SetFinal();
       
  1801 		}
       
  1802 	else if(aPacket.RemainingInsertSpace() == startspace)
       
  1803 		{
       
  1804 		// There are pending header or data but we inserted nothing! 
       
  1805 		// Some header isn't fitting into the packets provided. 
       
  1806 		FLOG(_L("PrepareNextSendPacket - nothing was actually inserted\r\n"));
       
  1807 		iSendProgress = EError;
       
  1808 		}
       
  1809 
       
  1810 	return(iSendProgress);
       
  1811 	}
       
  1812 
       
  1813 /**
       
  1814 Prepare the object for receiving into.
       
  1815 @internalComponent
       
  1816 */
       
  1817 TInt CObexBaseObject::InitReceive()
       
  1818 	{
       
  1819 	FLOG(_L("CObexBaseObject::InitReceive\r\n"));
       
  1820 
       
  1821 	// Always clear the object out before allowing it to receive anything
       
  1822 	Reset();
       
  1823 	iRecvBytes = 0;
       
  1824 	iRecvProgress = EContinue;
       
  1825 	return(KErrNone);
       
  1826 	}
       
  1827 
       
  1828 /**
       
  1829 Parse the passed packet, consuming headers into this object as appropriate.
       
  1830 The returned progress can not be relied upon to indicate completion, because
       
  1831 that is actually signalled at a diferent level, depending on the source of
       
  1832 the packet(final bit or server complete response). Returning EComplete 
       
  1833 simply indicates that all of the object body has been received.
       
  1834 
       
  1835 @param aPacket The packet to extract the headers from
       
  1836 
       
  1837 @return The progress of header extraction
       
  1838 @internalComponent
       
  1839 */
       
  1840 CObexBaseObject::TProgress CObexBaseObject::ParseNextReceivePacket(CObexPacket &aPacket)
       
  1841 	{
       
  1842 	iLastError = ERespInternalError;
       
  1843 	FLOG(_L("CObexBaseObject::ParseNextReceivePacket\r\n"));
       
  1844 	
       
  1845 	if(iRecvProgress != EContinue && iRecvProgress != EComplete)
       
  1846 		{
       
  1847 		FLOG(_L("CObexBaseObject::ParseNextReceivePacket Error!!! Exiting\r\n"));
       
  1848 		return(iSendProgress);
       
  1849 		}
       
  1850 	TObexInternalHeader header;
       
  1851 
       
  1852 	while(aPacket.ExtractData(header))
       
  1853 		{
       
  1854 		switch(header.HI())
       
  1855 			{
       
  1856 		case TObexInternalHeader::EConnectionID:
       
  1857 			{
       
  1858 			if ( iHeaderMask & KObexHdrConnectionID )
       
  1859 				{
       
  1860 				FLOG(_L("ParseNextReceivePacket extracting CONNECTIONID\r\n"));
       
  1861 
       
  1862 				iValidHeaders &= ~KObexHdrConnectionID;
       
  1863 
       
  1864 			 	TRAPD(err, SetConnectionIdL(header.HVInt()));
       
  1865 
       
  1866 				if (err)
       
  1867 					{
       
  1868 					return EError;
       
  1869 					}
       
  1870 				}
       
  1871 			}
       
  1872 			break;
       
  1873 		case TObexInternalHeader::EAppParam:
       
  1874 			{
       
  1875 			if ( iHeaderMask & KObexHdrAppParam )
       
  1876 				{
       
  1877 				FLOG(_L("ParseNextReceivePacket extracting APPPARAM\r\n"));
       
  1878 				iValidHeaders &= ~KObexHdrAppParam;
       
  1879 
       
  1880 		
       
  1881 				TPtrC8 src(header.HVByteSeq(), header.HVSize());
       
  1882 				TRAPD(err, SetAppParamL(src));
       
  1883 				if (err)
       
  1884 					{
       
  1885 					return EError;
       
  1886 					}
       
  1887 					
       
  1888 				iValidHeaders |= KObexHdrAppParam; 
       
  1889 				}
       
  1890 			}
       
  1891 			break;
       
  1892 		case TObexInternalHeader::EHttp:
       
  1893 			{
       
  1894 			FLOG(_L("ParseNextReceivePacket extracting Http\r\n"));
       
  1895 			
       
  1896 			TPtrC8 src(header.HVByteSeq(), header.HVSize());
       
  1897 			
       
  1898 			TRAPD(err, AddHttpL(src));
       
  1899 			
       
  1900 			if (err)
       
  1901 				{
       
  1902 				return EError;
       
  1903 				}
       
  1904 			}
       
  1905 			break;
       
  1906 		case TObexInternalHeader::EName:
       
  1907 			{
       
  1908 			if(iHeaderMask & KObexHdrName) 
       
  1909 				{ 
       
  1910 				FLOG(_L("ParseNextReceivePacket Extracting NAME"));
       
  1911 				iValidHeaders &= ~KObexHdrName;
       
  1912 
       
  1913 				HBufC* newHeader = HBufC::New(header.HVSize());
       
  1914 				if (!newHeader)
       
  1915 					{
       
  1916 					return EError;
       
  1917 					}
       
  1918 				//else
       
  1919 				TPtr ptr(newHeader->Des()); 
       
  1920 				
       
  1921 				TInt err = KErrNone;
       
  1922 				
       
  1923 				if(header.GetHVText(ptr) == KErrNone) 
       
  1924 					{
       
  1925 					TRAP(err, SetNameL(*newHeader));
       
  1926 					}
       
  1927 				delete newHeader;
       
  1928 				newHeader = NULL;
       
  1929 				
       
  1930 				if (err)
       
  1931 					{
       
  1932 					return EError;
       
  1933 					}
       
  1934 				}
       
  1935 				
       
  1936 			}
       
  1937 			break;
       
  1938 		case TObexInternalHeader::EType:
       
  1939 			{
       
  1940 			if(iHeaderMask & KObexHdrType) 
       
  1941 				{ 
       
  1942 				FLOG(_L("ParseNextReceivePacket extracting TYPE\r\n"));
       
  1943 				iValidHeaders &= ~KObexHdrType;
       
  1944 
       
  1945 				TPtrC8 src(header.HVByteSeq(), header.HVSize());
       
  1946 				// use SetTypeL(), to ensure null terms are handled correctly
       
  1947 				TRAPD(err, SetTypeL(src));
       
  1948 				if (err)
       
  1949 					{
       
  1950 					return EError;
       
  1951 					}
       
  1952 
       
  1953 				FLOG(_L("ParseNextReceivePacket extracting TYPE\r\n"));
       
  1954 				}
       
  1955 			}
       
  1956 			break;
       
  1957 		case TObexInternalHeader::ELength:
       
  1958 			{
       
  1959 			if(iHeaderMask & KObexHdrLength)
       
  1960 				{
       
  1961 				FLOG(_L("ParseNextReceivePacket extracting LENGTH\r\n"));
       
  1962 				TRAPD(err, SetLengthL(header.HVInt()));
       
  1963 
       
  1964 				if (err)
       
  1965 					{
       
  1966 					return EError;
       
  1967 					}
       
  1968 
       
  1969 				iValidHeaders |= KObexHdrLength;
       
  1970 				}
       
  1971 			}
       
  1972 			break;
       
  1973 		case TObexInternalHeader::ETime:// Time is ISO 8601 format byte sequence.
       
  1974 			{
       
  1975 			if(iHeaderMask & KObexHdrTime)
       
  1976 				{
       
  1977 				FLOG(_L("ParseNextReceivePacket extracting TIME in ISO 8601 format\r\n"));
       
  1978 				TInt err = KErrGeneral;
       
  1979 				TTime time;
       
  1980 				
       
  1981 				// Use Win2k's incorrect TIME format header to calculate the size required.
       
  1982 				// 2k inserts incorrect padding and uses Unicode format.  Allow a little extra
       
  1983 				// just in case.  (Currently this should be 48 bytes)
       
  1984 				static const TInt KMaxTIMESize = sizeof("yyyy.mm.ddThh:mm:ssZ") * 2 + 6;
       
  1985 				TBuf<KMaxTIMESize> timebuf;
       
  1986 				
       
  1987 				if(header.GetHVText(timebuf) == KErrNone && timebuf.LocateF('t') >= 0)
       
  1988 					{
       
  1989 					// Win2k sends an invalid TIME header, inserting unicode into a ByteSeq
       
  1990 					// header, and inserting . and : characters between fields.  So copy char
       
  1991 					// by char, ignoring invalid characters.
       
  1992 					TBuf8<16> narrowTime;
       
  1993 #ifdef _DEBUG
       
  1994 					TBool changed = EFalse;
       
  1995 #endif
       
  1996 					for (TInt copyByte = 0; copyByte <= timebuf.Length()-1; copyByte++)
       
  1997 						{
       
  1998 						TChar chr(timebuf[copyByte]);
       
  1999 						if (chr && (chr != 0x2e /* . */) && (chr != 0x3a /* : */))
       
  2000 							{
       
  2001 							if (narrowTime.Length() < narrowTime.MaxLength())
       
  2002 								{
       
  2003 								narrowTime.Append(chr);
       
  2004 								}
       
  2005 							}
       
  2006 #ifdef _DEBUG
       
  2007 						else
       
  2008 							{
       
  2009 							changed = ETrue;
       
  2010 							}
       
  2011 #endif
       
  2012 						}
       
  2013 					
       
  2014 					// As we've mangled the header, output a log entry just in case...
       
  2015 					FTRACE(if (changed) FLOG(_L(" - Windows non-compliant time header detected and converted")));
       
  2016 
       
  2017 					TRAP(err, SetTimeHeaderL(narrowTime));
       
  2018 					}
       
  2019 
       
  2020 				if(err)
       
  2021 					{
       
  2022 					// Adding TIME header to object failed (out of memory?).
       
  2023 					FLOG(_L("ParseNextReceivePacket extracting TIME in ISO 8601 format failed"));
       
  2024 
       
  2025 					// if adding TIME header to object failed, the header is ignored and the packet accepted
       
  2026 					iValidHeaders &= ~KObexHdrTime;
       
  2027 					}
       
  2028 				else
       
  2029 					{
       
  2030 					// Adding TIME header succeeded, make a note.
       
  2031 					iValidHeaders |= KObexHdrTime;
       
  2032 					}
       
  2033 				}
       
  2034 			}
       
  2035 			break;
       
  2036 		case KFourByteTimeHeaderAddress : // Time is no. of secs since 1/1/1970
       
  2037 			if (iHeaderMask & KObexHdrTime)
       
  2038 				{
       
  2039 				FLOG(_L("ParseNextReceivePacket extracting TIME in secs since 1/1/1970"));
       
  2040 				TTimeIntervalSeconds secs = header.HVInt();
       
  2041 				TRAPD(err, SetTimeL(TTime(TDateTime(1970, EJanuary, 0, 0, 0, 0, 0)) + secs));
       
  2042 			
       
  2043 				if(err)
       
  2044 					{
       
  2045 					return EError;
       
  2046 					}
       
  2047 
       
  2048 				iValidHeaders |= KObexHdrTime;
       
  2049 				}
       
  2050 			break;
       
  2051 		case TObexInternalHeader::EDescription:
       
  2052 			{
       
  2053 			if(iHeaderMask & KObexHdrDescription) 
       
  2054 				{ 
       
  2055 				FLOG(_L("ParseNextReceivePacket extracting DESCRIPTION\r\n"));
       
  2056 				iValidHeaders &= ~KObexHdrDescription;
       
  2057 
       
  2058 				HBufC* newHeader = HBufC::New(header.HVSize());
       
  2059 				if (!newHeader)
       
  2060 					{
       
  2061 					return EError;
       
  2062 					}
       
  2063 				//else
       
  2064 				TPtr ptr(newHeader->Des()); 
       
  2065 
       
  2066 				TInt err = KErrNone;
       
  2067 				
       
  2068 				if(header.GetHVText(ptr) == KErrNone) 
       
  2069 					{
       
  2070 					TRAP(err, SetDescriptionL(*newHeader));
       
  2071 					}
       
  2072 				delete newHeader;
       
  2073 				newHeader = NULL;
       
  2074 				
       
  2075 				if (err)
       
  2076 					{
       
  2077 					return EError;
       
  2078 					}
       
  2079 				}
       
  2080 			}
       
  2081 			break;
       
  2082 		case TObexInternalHeader::ECount:
       
  2083 			{
       
  2084 			if(iHeaderMask & KObexHdrCount) 
       
  2085 				{ 
       
  2086 				FLOG(_L("ParseNextReceivePacket extracting Count\r\n"));
       
  2087 
       
  2088 				CObexHeader* newHeader = NULL;
       
  2089 				TRAPD( err, newHeader = CObexHeader::NewL());
       
  2090 				if (err)
       
  2091 					{
       
  2092 					return EError;
       
  2093 					}
       
  2094 				newHeader->SetFourByte(TObexInternalHeader::ECount, header.HVInt());
       
  2095 
       
  2096 				//Transfer ownership of pointer to CObexHeaderSet
       
  2097 				err = iHeaderSet->AddHeader(newHeader);
       
  2098 				if (err)
       
  2099 					{
       
  2100 					delete newHeader;
       
  2101 					newHeader = NULL;
       
  2102 					return EError;
       
  2103 					}
       
  2104 				iValidHeaders |= KObexHdrCount;
       
  2105 				}
       
  2106 			}
       
  2107 			break;
       
  2108 		case TObexInternalHeader::ETarget:
       
  2109 			{
       
  2110 			if(iHeaderMask & KObexHdrTarget) 
       
  2111 				{ 
       
  2112 				FLOG(_L("ParseNextReceivePacket extracting TARGET\r\n"));
       
  2113 				iValidHeaders &= ~KObexHdrTarget;
       
  2114 
       
  2115 				TPtrC8 src(header.HVByteSeq(), header.HVSize());
       
  2116 				TRAPD(err, SetTargetL(src));
       
  2117 				if (err)
       
  2118 					{
       
  2119 					return EError;
       
  2120 					}
       
  2121 				}
       
  2122 			}
       
  2123 			break;
       
  2124 		case TObexInternalHeader::ECreatorID:
       
  2125 			{
       
  2126 			if(iHeaderMask & KObexHdrCreatorID) 
       
  2127 				{
       
  2128 				FLOG(_L("ParseNextReceivePacket Extracting CreatorID header"));
       
  2129 
       
  2130 				CObexHeader* fourByteHeader = NULL;
       
  2131 				TRAPD( err, fourByteHeader = CObexHeader::NewL());
       
  2132 				if (err)
       
  2133 					{
       
  2134 					return EError;
       
  2135 					}
       
  2136 				fourByteHeader->SetFourByte(TObexInternalHeader::ECreatorID, header.HVInt());
       
  2137 				//Transfer ownership of pointer to CObexHeaderSet
       
  2138 				err = iHeaderSet->AddHeader(fourByteHeader);
       
  2139 				if (err)
       
  2140 					{
       
  2141 					delete fourByteHeader;
       
  2142 					fourByteHeader = NULL;
       
  2143 					return EError;
       
  2144 					}
       
  2145 				iValidHeaders |= KObexHdrCreatorID;
       
  2146 				}
       
  2147 			}
       
  2148 			break;
       
  2149 		case TObexInternalHeader::EWanUUID:
       
  2150 			{
       
  2151 			if(iHeaderMask & KObexHdrWanUUID) 
       
  2152 				{
       
  2153 				FLOG(_L("ParseNextReceivePacket Extracting WanUUID header"));					
       
  2154 				TPtrC8 src(header.HVByteSeq(), header.HVSize());
       
  2155 	
       
  2156 				CObexHeader* byteseqHeader = NULL;
       
  2157 
       
  2158 				byteseqHeader = IrOBEXHeaderUtil::CreateAndSetByteSeqHeader(TObexInternalHeader::EWanUUID, src);
       
  2159 				if (!byteseqHeader)
       
  2160 					{
       
  2161 					return EError;
       
  2162 					}
       
  2163 
       
  2164 				//Transfer ownership of pointer to CObexHeaderSet
       
  2165 				TInt err = iHeaderSet->AddHeader(byteseqHeader);
       
  2166 				if (err)
       
  2167 					{
       
  2168 					delete byteseqHeader;
       
  2169 					byteseqHeader = NULL;
       
  2170 					return EError;
       
  2171 					}
       
  2172 
       
  2173 				iValidHeaders |= KObexHdrWanUUID;
       
  2174 				}
       
  2175 			}
       
  2176 			break;
       
  2177 		case TObexInternalHeader::EObjectClass:
       
  2178 			{
       
  2179 			if(iHeaderMask & KObexHdrObjectClass) 
       
  2180 				{
       
  2181 				FLOG(_L("ParseNextReceivePacket Extracting WanUUID header"));					
       
  2182 				TPtrC8 src(header.HVByteSeq(), header.HVSize());
       
  2183 	
       
  2184 				CObexHeader* byteseqHeader = NULL;
       
  2185 
       
  2186 				byteseqHeader = IrOBEXHeaderUtil::CreateAndSetByteSeqHeader(TObexInternalHeader::EObjectClass, src);
       
  2187 				if (!byteseqHeader)
       
  2188 					{
       
  2189 					return EError;
       
  2190 					}
       
  2191 
       
  2192 				//Transfer ownership of pointer to CObexHeaderSet
       
  2193 				TInt err = iHeaderSet->AddHeader(byteseqHeader);
       
  2194 				if (err)
       
  2195 					{
       
  2196 					delete byteseqHeader;
       
  2197 					byteseqHeader = NULL;
       
  2198 					return EError;
       
  2199 					}
       
  2200 
       
  2201 				iValidHeaders |= KObexHdrObjectClass;
       
  2202 				}
       
  2203 			}
       
  2204 			break;
       
  2205  		case TObexInternalHeader::EBody:
       
  2206  			iValidHeaders |= KObexHdrBody;
       
  2207  			//Fall-through
       
  2208 		case TObexInternalHeader::EEndOfBody:
       
  2209 			{
       
  2210 			FLOG(_L("ParseNextReceivePacket extracting BODY\r\n"));
       
  2211 			TPtr8 ptr(header.HVByteSeq(), header.HVSize(), header.HVSize());
       
  2212 
       
  2213 			if(header.HI() == TObexInternalHeader::EEndOfBody)
       
  2214 				{// Body finished, there _could_ still be more headers, however...
       
  2215 				iValidHeaders |= KObexHdrEndOfBody;
       
  2216 				FLOG(_L("ParseNextReceivePacket extracting ENDOFBODY\r\n"));
       
  2217 				iRecvProgress = EComplete;
       
  2218 				}
       
  2219 
       
  2220 			NewData(iRecvBytes, ptr);
       
  2221 			if(ptr.Length() < header.HVSize())
       
  2222 				{
       
  2223 				return(iRecvProgress = EError);
       
  2224 				}
       
  2225 			iRecvBytes += ptr.Length();
       
  2226 			}
       
  2227 			break;
       
  2228 		case TObexInternalHeader::EAuthChallenge:
       
  2229 			{
       
  2230 			iLastError = ERespUnauthorized;
       
  2231 			return EError;
       
  2232 			}
       
  2233 		default:
       
  2234 			{
       
  2235 			// Non Standard header received so check for user defined header
       
  2236 			// NB. All user defined headers are in range 0x30..0x3F
       
  2237 
       
  2238 			if ((iHeaderMask & KObexHdrUserDefined) &&
       
  2239 			    ((header.HI() & 0x30) != 0))
       
  2240 				{
       
  2241 				FLOG(_L("ParseNextReceivePacket Extracting User Defined Unicode header"));
       
  2242 				if( IrOBEXHeaderUtil::ParseHeader(header, *iHeaderSet) == KErrNone)
       
  2243 					{
       
  2244 					iValidHeaders |= KObexHdrUserDefined;
       
  2245 					}
       
  2246 				else
       
  2247 					{
       
  2248 					return EError;
       
  2249 					}
       
  2250 				}
       
  2251 			
       
  2252 			}	//	End of default
       
  2253 				
       
  2254 			}	//	End of header type switch
       
  2255 		}	//	End of while
       
  2256 
       
  2257 	return(iRecvProgress);
       
  2258 	}
       
  2259 
       
  2260 /**
       
  2261 Returns the Obex Error response code from the last call to CObexBaseObject::ParseNextReceivePacket
       
  2262 
       
  2263 @return The Obex Response code
       
  2264 @internalComponent
       
  2265 */
       
  2266 
       
  2267 TObexResponse CObexBaseObject::GetLastError() const
       
  2268 	{
       
  2269 	return iLastError;
       
  2270 	}
       
  2271 
       
  2272 /**
       
  2273 Sets the header mask. aHeaderMask is built up by bit-wise ‘or’ing any of 
       
  2274 the KObexHdr... constants.
       
  2275 For example, if it is set to KObexHdrName | KObexHdrLength, only 
       
  2276 these two headers will be specified in transfer operations with the remote 
       
  2277 machine, even if there are other valid attributes which could be used. In 
       
  2278 effect, this mask is bit-wise ‘and’ed with the "valid headers" mask when 
       
  2279 determining which headers are valid for the purposes of transfers.
       
  2280 
       
  2281 @param aHeaderMask: the header mask to be set
       
  2282 
       
  2283 @publishedAll
       
  2284 @released
       
  2285 **/
       
  2286 EXPORT_C void CObexBaseObject::SetHeaderMask(const TObexHeaderMask aHeaderMask)
       
  2287 	{
       
  2288 	LOG_LINE
       
  2289 	LOG_FUNC
       
  2290 
       
  2291 	iHeaderMask=aHeaderMask;
       
  2292 	}
       
  2293 
       
  2294 /**
       
  2295 Returns the number of bytes of the body of the object transferred so far 
       
  2296 while sending this object.
       
  2297 
       
  2298 @return The number of bytes sent
       
  2299 
       
  2300 @publishedAll
       
  2301 @released
       
  2302 **/
       
  2303 EXPORT_C TInt CObexBaseObject::BytesSent()
       
  2304 	{
       
  2305 	LOG_LINE
       
  2306 	LOG_FUNC
       
  2307 
       
  2308 	return(iSendBytes);
       
  2309 	}
       
  2310 
       
  2311 /**
       
  2312 Returns the number of bytes of the body of the object transferred while 
       
  2313 receiving an object.
       
  2314 
       
  2315 @return The number of bytes received
       
  2316 @publishedAll
       
  2317 @released
       
  2318 */
       
  2319 EXPORT_C TInt CObexBaseObject::BytesReceived()
       
  2320 	{
       
  2321 	LOG_LINE
       
  2322 	LOG_FUNC
       
  2323 
       
  2324 	return(iRecvBytes);
       
  2325 	}
       
  2326 
       
  2327 /**
       
  2328 Returns the currently set header mask. This defaults to 0xFF (i.e. allow 
       
  2329 everything) when Reset () or InitFromFileL is called. This does not specify 
       
  2330 which headers currently contain valid data--merely which headers will be 
       
  2331 transferred if they do contain valid data.
       
  2332 
       
  2333 @return The currently set header mask
       
  2334 @publishedAll
       
  2335 @released
       
  2336 */
       
  2337 EXPORT_C TObexHeaderMask CObexBaseObject::HeaderMask()
       
  2338 	{
       
  2339 	LOG_LINE
       
  2340 	LOG_FUNC
       
  2341 
       
  2342 	return iHeaderMask;
       
  2343 	}
       
  2344 
       
  2345 /**
       
  2346 Returns the current valid header mask. This allows inspection of the current
       
  2347 set of valid headers, particularly useful for determining whether a put
       
  2348 object contained a body header (important for deleting files as part of file
       
  2349 transfer).
       
  2350 
       
  2351 @return The current valid header mask
       
  2352 @publishedAll
       
  2353 @released
       
  2354 */
       
  2355 EXPORT_C TObexHeaderMask CObexBaseObject::ValidHeaders()
       
  2356 	{
       
  2357 	LOG_LINE
       
  2358 	LOG_FUNC
       
  2359 
       
  2360 	return iValidHeaders;
       
  2361 	}