bluetoothappprofiles/avrcp/avrcpipc/src/ipc.cpp
changeset 70 f5508c13dfe0
parent 67 16e4b9007960
child 71 083fd884d7dd
equal deleted inserted replaced
67:16e4b9007960 70:f5508c13dfe0
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /** 
       
    17  @file
       
    18  @internalTechnology
       
    19  @released
       
    20 */
       
    21 
       
    22 #include <e32debug.h>
       
    23 #include <remconmediaerror.h>
       
    24 #include "avrcpipcutils.h"
       
    25 #include "avrcpinternalinterface.h"
       
    26 #include "mediabrowse.h"
       
    27 #include "mediainformation.h"
       
    28 #include "nowplaying.h"
       
    29 #include "playerinformation.h"
       
    30 
       
    31 /*
       
    32  * These methods are intended to provide structured IPC communication between
       
    33  * the AVRCP bearer, and the client API DLLs. They are intended to be 'simple'
       
    34  * classes, in which the basic operation are as follows:
       
    35  *
       
    36  *   reading: call ReadL(request) and pull information out of member variables
       
    37  *   writing: put information into member variables, then call WriteL(request)
       
    38  *
       
    39  * The ReadL() and WriteL() methods effectively just serialize the information
       
    40  * already stored in the member varables. However, they serialize in Big-Endian
       
    41  * format, so that after calling WriteL() and then sending the response back to
       
    42  * the AVRCP bearer via IPC, the bearer can just append the response straight
       
    43  * into an AVC frame; no bit-twiddling is necessary.
       
    44  *
       
    45  * Therefore it is important that these classes _ALWAYS_ write in Big-Endian
       
    46  * format, and write out responses that conform to the AVRCP specification for
       
    47  * PDUs listed in sections 5.1 - 5.4 of the AVRCP 1.3 specification. The ReadL()
       
    48  * operation is the inverse of the WriteL() operation and reads an AVRCP request
       
    49  * in the format listed in the AVRCP specification.
       
    50  *
       
    51  * There's also a Size() method, which will return the size of the response
       
    52  * before WriteL() is called. This is required particularly for responses with
       
    53  * text strings so that the correct-sized buffer can be allocated, as these
       
    54  * could be very large responses (theoretically up to 16 megabytes!) sent via
       
    55  * IPC (just once) and then kept and fragmented in the AVRCP bearer. The Close()
       
    56  * method frees up any memory allocated with these classes.
       
    57  */
       
    58 
       
    59 
       
    60 // --------------------------------------------------------------------------------
       
    61 // Used for constructing PDU 0x30 responses
       
    62 
       
    63 EXPORT_C void RRemConPlayerInformationGetPlayStatusResponse::ReadL(const TDesC8& aData)
       
    64 	{
       
    65 	iReadStream.Open(aData);
       
    66 	iTrackLength      = Read32L();
       
    67 	iPlayPos          = Read32L();
       
    68 	iStatus           = (MPlayerEventsObserver::TPlaybackStatus) Read8L();
       
    69 	iReadStream.Close();
       
    70 	}
       
    71 
       
    72 EXPORT_C void RRemConPlayerInformationGetPlayStatusResponse::WriteL(TDes8& aOutData)
       
    73 	{
       
    74 	aOutData.Zero();
       
    75 	iStream.Open(aOutData);
       
    76 	Write32L(KErrNone);   // Successful operation
       
    77 	Write32L(iTrackLength);
       
    78 	Write32L(iPlayPos);
       
    79 	Write8L(iStatus);
       
    80 	iStream.CommitL();
       
    81 	}
       
    82 
       
    83 // --------------------------------------------------------------------------------
       
    84 // Used for constructing PDU 0xff requests
       
    85 
       
    86 EXPORT_C void RRemConPlayerInformationGetPlayStatusUpdateRequest::ReadL(const TDesC8& aData)
       
    87 	{
       
    88 	iReadStream.Open(aData);
       
    89 	iStatus           = (MPlayerEventsObserver::TPlaybackStatus) Read8L();
       
    90 	iReadStream.Close();
       
    91 	}
       
    92 
       
    93 EXPORT_C void RRemConPlayerInformationGetPlayStatusUpdateRequest::WriteL(TDes8& aOutData)
       
    94 	{
       
    95 	aOutData.Zero();
       
    96 	iStream.Open(aOutData);
       
    97 	Write8L(iStatus);
       
    98 	iStream.CommitL();
       
    99 	}
       
   100 
       
   101 // --------------------------------------------------------------------------------
       
   102 // Used for constructing PDU 0xff responses
       
   103 
       
   104 EXPORT_C void RRemConPlayerInformationGetPlayStatusUpdateResponse::ReadL(const TDesC8& aData)
       
   105 	{
       
   106 	iReadStream.Open(aData);
       
   107 	iStatus           = (MPlayerEventsObserver::TPlaybackStatus) Read8L();
       
   108 	iReadStream.Close();
       
   109 	}
       
   110 
       
   111 EXPORT_C void RRemConPlayerInformationGetPlayStatusUpdateResponse::WriteL(TDes8& aOutData)
       
   112 	{
       
   113 	aOutData.Zero();
       
   114 	iStream.Open(aOutData);
       
   115 	Write32L(KErrNone);   // Successful operation
       
   116 	Write8L(iStatus);
       
   117 	iStream.CommitL();
       
   118 	}
       
   119 // --------------------------------------------------------------------------------
       
   120 // Used for constructing PDU 0x15 and PDU 0x16 responses
       
   121 
       
   122 EXPORT_C void RRemConGetPlayerApplicationTextResponse::ReadL(const TDesC8& aData)
       
   123 	{
       
   124 	iReadStream.Open(aData);
       
   125 	iNumberAttributes = Read8L();
       
   126 	for (TInt i = 0; i < iNumberAttributes; i++ )
       
   127 		{
       
   128 		RSettingWithCharset setting;
       
   129 		CleanupClosePushL(setting);
       
   130 		setting.iAttributeId = Read8L();
       
   131 		setting.iCharset     = Read16L();
       
   132 		setting.iStringLen   = Read8L();
       
   133 		setting.iString      = HBufC8::NewL(setting.iStringLen);
       
   134 		TPtr8 ptr            = setting.iString->Des();
       
   135 		iReadStream.ReadL(ptr);
       
   136 		iAttributes.AppendL(setting);
       
   137 		CleanupStack::Pop(&setting);
       
   138 		}
       
   139 	
       
   140 	}
       
   141 
       
   142 EXPORT_C void RRemConGetPlayerApplicationTextResponse::WriteL(TDes8& aOutData)
       
   143 	{
       
   144 	// The caller should have called Size() to pre-allocate enough buffer space
       
   145 	__ASSERT_DEBUG(aOutData.MaxLength() >= Size(), AvrcpIpcUtils::Panic(EAvrcpIpcCommandDataTooLong));
       
   146 	aOutData.Zero();
       
   147 	iStream.Open(aOutData);
       
   148 	Write32L(KErrNone);   // Successful operation
       
   149 	Write8L(iNumberAttributes);
       
   150 	for (TInt i = 0; i < iNumberAttributes; i++ )
       
   151 		{
       
   152 		Write8L(iAttributes[i].iAttributeId);
       
   153 		Write16L(iAttributes[i].iCharset);
       
   154 		Write8L(iAttributes[i].iStringLen);
       
   155 		iStream.WriteL(iAttributes[i].iString->Des());
       
   156 		}
       
   157 	iStream.CommitL();
       
   158 	}
       
   159 
       
   160 EXPORT_C TInt RRemConGetPlayerApplicationTextResponse::Size()
       
   161 	{
       
   162 	// Return the size that a buffer needs to be allocated to
       
   163 	// serialise the data encapsulated within this data structure.
       
   164 	
       
   165 	TInt size = 5; // 5 bytes: status code + number attributes
       
   166 	for (TInt i = 0; i < iNumberAttributes; i++)
       
   167 		{
       
   168 		size += 4;   // 4 bytes: attribute id + charset + stringlen
       
   169 		size += iAttributes[i].iString->Length();
       
   170 		}
       
   171 	return size;
       
   172 	}
       
   173 
       
   174 EXPORT_C void RRemConGetPlayerApplicationTextResponse::Close()
       
   175 	{
       
   176 	for (TInt i = 0; i < iAttributes.Count(); i++)
       
   177 		{
       
   178 		iAttributes[i].Close();
       
   179 		}
       
   180 	iAttributes.Close();
       
   181 	RAvrcpIPC::Close();
       
   182 	}
       
   183 
       
   184 // --------------------------------------------------------------------------------
       
   185 // Used for constructing PDU 0x10 responses
       
   186 
       
   187 EXPORT_C void RRemConGetCapabilitiesResponse::ReadL(const TDesC8& aData)
       
   188 	{
       
   189 	iReadStream.Open(aData);
       
   190 	iCapabilityId     = Read8L();
       
   191 	if (   iCapabilityId != ECapabilityIdCompanyID
       
   192 	    && iCapabilityId != ECapabilityIdEventsSupported)
       
   193 		{
       
   194 		iReadStream.Close();
       
   195 		User::Leave(KErrNotSupported);
       
   196 		}
       
   197 	
       
   198 	iCapabilityCount  = Read8L();
       
   199 	for (TInt i = 0; i < iCapabilityCount; i++ )
       
   200 		{
       
   201 		if (iCapabilityId == ECapabilityIdCompanyID)
       
   202 			{
       
   203 			iCapabilities.AppendL(Read24L());  // Read 3 bytes
       
   204 			}
       
   205 		else
       
   206 			{
       
   207 			iCapabilities.AppendL(Read8L());   // Read 1 byte
       
   208 			}
       
   209 		}
       
   210 	iReadStream.Close();
       
   211 	}
       
   212 
       
   213 EXPORT_C void RRemConGetCapabilitiesResponse::WriteL(TDes8& aOutData)
       
   214 	{
       
   215 	if (   iCapabilityId != ECapabilityIdCompanyID
       
   216 	    && iCapabilityId != ECapabilityIdEventsSupported)
       
   217 		{
       
   218 		User::Leave(KErrNotSupported);
       
   219 		}
       
   220 	aOutData.Zero();
       
   221 	iStream.Open(aOutData);
       
   222 	Write32L(KErrNone);   // Successful operation
       
   223 	Write8L(iCapabilityId);
       
   224 	Write8L(iCapabilityCount);
       
   225 	for (TInt i = 0; i < iCapabilityCount; i++ )
       
   226 		{
       
   227 		if (iCapabilityId == ECapabilityIdCompanyID)
       
   228 			{
       
   229 			Write24L(iCapabilities[i]);  // Write 3 bytes
       
   230 			}
       
   231 		else
       
   232 			{
       
   233 			Write8L(iCapabilities[i]);   // Write 1 byte
       
   234 			}
       
   235 		}
       
   236 	iStream.CommitL();
       
   237 	}
       
   238 
       
   239 // --------------------------------------------------------------------------------
       
   240 // Used for constructing and parsing PDU 0x13 (response) and PDU 0x14 (request)
       
   241 
       
   242 EXPORT_C void RRemConPlayerAttributeIdsAndValues::ReadL(const TDesC8& aData)
       
   243 	{
       
   244 	iReadStream.Open(aData);
       
   245 	iNumberAttributes = Read8L();
       
   246 	for (TInt i = 0; i < iNumberAttributes; i++ )
       
   247 		{
       
   248 		TInt attributeId     = Read8L();
       
   249 		TInt attributeValue = Read8L();
       
   250 		iAttributeId.AppendL(attributeId);
       
   251 		iAttributeValue.AppendL(attributeValue);
       
   252 		}
       
   253 	iReadStream.Close();
       
   254 	}
       
   255 
       
   256 EXPORT_C void RRemConPlayerAttributeIdsAndValues::WriteL(TDes8& aOutData)
       
   257 	{
       
   258 	aOutData.Zero();
       
   259 	iStream.Open(aOutData);
       
   260 	Write32L(KErrNone);   // Successful operation
       
   261 	Write8L(iNumberAttributes);
       
   262 	for (TInt i = 0; i < iNumberAttributes; i++ )
       
   263 		{
       
   264 		Write8L(iAttributeId[i]);
       
   265 		Write8L(iAttributeValue[i]);
       
   266 		}
       
   267 	iStream.CommitL();
       
   268 	}
       
   269 
       
   270 // --------------------------------------------------------------------------------
       
   271 // Used for constructing PDU 0x11 and PDU 0x12 responses
       
   272 
       
   273 EXPORT_C void RRemConPlayerListOfAttributes::ReadL(const TDesC8& aData)
       
   274 	{
       
   275 	iReadStream.Open(aData);
       
   276 	iNumberAttributes = Read8L();
       
   277 	for (TInt i = 0; i < iNumberAttributes; i++ )
       
   278 		{
       
   279 		TInt attribute = Read8L();
       
   280 		iAttributes.AppendL(attribute);
       
   281 		}
       
   282 	iReadStream.Close();
       
   283 	}
       
   284 
       
   285 EXPORT_C void RRemConPlayerListOfAttributes::WriteL(TDes8& aOutData)
       
   286 	{
       
   287 	aOutData.Zero();
       
   288 	iStream.Open(aOutData);
       
   289 	iAttributes.Sort();
       
   290 	Write32L(KErrNone);   // Successful operation
       
   291 	Write8L(iNumberAttributes);
       
   292 	for (TInt i = 0; i < iNumberAttributes; i++ )
       
   293 		{
       
   294 		Write8L(iAttributes[i]);
       
   295 		}
       
   296 	iStream.CommitL();
       
   297 	}
       
   298 
       
   299 // --------------------------------------------------------------------------------
       
   300 // Used for parsing PDU 0x20 requests
       
   301 
       
   302 EXPORT_C void RRemConGetElementAttributesRequest::ReadL(const TDesC8& aData)
       
   303 	{
       
   304 	iReadStream.Open(aData);
       
   305 	iElement = Read64L();
       
   306 	iNumberAttributes = Read8L();
       
   307 	
       
   308 	for (TInt i = 0; i < iNumberAttributes; i++ )
       
   309 		{
       
   310 		TInt attribute = Read32L();
       
   311 		iAttributes.AppendL(attribute);
       
   312 		}
       
   313 	iReadStream.Close();
       
   314 	}
       
   315 
       
   316 EXPORT_C void RRemConGetElementAttributesRequest::WriteL(TDes8& aOutData)
       
   317 	{
       
   318 	aOutData.Zero();
       
   319 	iStream.Open(aOutData);
       
   320 	iAttributes.Sort();
       
   321 	Write32L(KErrNone);   // Successful operation
       
   322 	
       
   323 	// 64 bits of data
       
   324 	Write64L(iElement);
       
   325 	Write8L(iNumberAttributes);
       
   326 
       
   327 	for (TInt i = 0; i < iNumberAttributes; i++ )
       
   328 		{
       
   329 		Write32L(iAttributes[i]);
       
   330 		}
       
   331 	iStream.CommitL();
       
   332 	}
       
   333 
       
   334 // --------------------------------------------------------------------------------
       
   335 // Used for PDU 0x20 responses
       
   336 
       
   337 EXPORT_C void RRemConGetElementAttributesResponse::ReadL(const TDesC8& aData)
       
   338 	{
       
   339 	iReadStream.Open(aData);
       
   340 	iNumberAttributes = Read8L();
       
   341 	
       
   342 	for (TInt i = 0; i < iNumberAttributes; i++ )
       
   343 		{
       
   344 		REAResponse eattr;
       
   345 		CleanupClosePushL(eattr);
       
   346 		eattr.iAttributeId = Read32L();
       
   347 		eattr.iCharset     = Read16L();
       
   348 		eattr.iStringLen   = Read16L();
       
   349 		eattr.iString      = HBufC8::NewL(eattr.iStringLen);
       
   350 		TPtr8 ptr          = eattr.iString->Des();
       
   351 		iReadStream.ReadL(ptr);
       
   352 		iAttributes.AppendL(eattr);
       
   353 		CleanupStack::Pop(&eattr);
       
   354 		}
       
   355 	
       
   356 	}
       
   357 
       
   358 EXPORT_C void RRemConGetElementAttributesResponse::WriteL(TDes8& aOutData)
       
   359 	{
       
   360 	__ASSERT_DEBUG(aOutData.MaxLength() >= Size(), AvrcpIpcUtils::Panic(EAvrcpIpcCommandDataTooLong));
       
   361 	aOutData.Zero();
       
   362 	iStream.Open(aOutData);
       
   363 	Write32L(KErrNone);   // Successful operation
       
   364 	
       
   365 	Write8L(iNumberAttributes);
       
   366 
       
   367 	for (TInt i = 0; i < iNumberAttributes; i++ )
       
   368 		{
       
   369 		Write32L(iAttributes[i].iAttributeId);
       
   370 		Write16L(iAttributes[i].iCharset);
       
   371 		Write16L(iAttributes[i].iStringLen);
       
   372 		iStream.WriteL(iAttributes[i].iString->Des());
       
   373 		}
       
   374 	iStream.CommitL();
       
   375 	}
       
   376 
       
   377 EXPORT_C TInt RRemConGetElementAttributesResponse::Size()
       
   378 	{
       
   379 	// Return the size that a buffer needs to be allocated to
       
   380 	// serialise the data encapsulated within this data structure.
       
   381 	
       
   382 	TInt size = 5; // 5 bytes: status code + number attributes
       
   383 	for (TInt i = 0; i < iNumberAttributes; i++)
       
   384 		{
       
   385 		size += 4+2+2; // 8 bytes: attrId (4 bytes) + charset (2 bytes) + stringlen (2 bytes)
       
   386 		size += iAttributes[i].iString->Length();
       
   387 		}
       
   388 	return size;
       
   389 	}
       
   390 
       
   391 EXPORT_C void RRemConGetElementAttributesResponse::Close()
       
   392 	{
       
   393 	for (TInt i = 0; i < iAttributes.Count(); i++)
       
   394 		{
       
   395 		iAttributes[i].Close();
       
   396 		}
       
   397 	iAttributes.Close();
       
   398 	RAvrcpIPC::Close();
       
   399 	}
       
   400 
       
   401 // --------------------------------------------------------------------------------
       
   402 
       
   403 EXPORT_C void RRemConPlayerInformation8BitResponse::ReadL(const TDesC8& aData)
       
   404 	{
       
   405 	iReadStream.Open(aData);
       
   406 	iValue = Read8L();
       
   407 	iReadStream.Close();
       
   408 	}
       
   409 
       
   410 EXPORT_C void RRemConPlayerInformation8BitResponse::WriteL(TDes8& aOutData)
       
   411 	{
       
   412 	aOutData.Zero();
       
   413 	iStream.Open(aOutData);
       
   414 	Write32L(KErrNone);   // Successful operation
       
   415 	
       
   416 	Write8L(iValue);
       
   417 	iStream.CommitL();
       
   418 	}
       
   419 
       
   420 // --------------------------------------------------------------------------------
       
   421 
       
   422 EXPORT_C void RRemConPlayerInformation32BitResponse::ReadL(const TDesC8& aData)
       
   423 	{
       
   424 	iReadStream.Open(aData);
       
   425 	iValue = Read32L();
       
   426 	iReadStream.Close();
       
   427 	}
       
   428 
       
   429 EXPORT_C void RRemConPlayerInformation32BitResponse::WriteL(TDes8& aOutData)
       
   430 	{
       
   431 	aOutData.Zero();
       
   432 	iStream.Open(aOutData);
       
   433 	Write32L(KErrNone);   // Successful operation
       
   434 	
       
   435 	Write32L(iValue);
       
   436 	iStream.CommitL();
       
   437 	}
       
   438 
       
   439 // --------------------------------------------------------------------------------
       
   440 
       
   441 EXPORT_C void RRemConPlayerInformation64BitResponse::ReadL(const TDesC8& aData)
       
   442 	{
       
   443 	iReadStream.Open(aData);
       
   444 	iValue = Read64L();
       
   445 	iReadStream.Close();
       
   446 	}
       
   447 
       
   448 EXPORT_C void RRemConPlayerInformation64BitResponse::WriteL(TDes8& aOutData)
       
   449 	{
       
   450 	aOutData.Zero();
       
   451 	iStream.Open(aOutData);
       
   452 	Write32L(KErrNone);   // Successful operation
       
   453 	
       
   454 	Write64L(iValue);
       
   455 	iStream.CommitL();
       
   456 	}
       
   457 
       
   458 // --------------------------------------------------------------------------------
       
   459 
       
   460 EXPORT_C void RSettingWithCharset::Close()
       
   461 	{
       
   462 	delete iString;
       
   463 	iString = NULL;
       
   464 	}
       
   465 
       
   466 EXPORT_C void REAResponse::Close()
       
   467 	{
       
   468 	delete iString;
       
   469 	iString = NULL;
       
   470 	}
       
   471 
       
   472 EXPORT_C void RRemConGetCapabilitiesResponse::Close()
       
   473 	{
       
   474 	iCapabilities.Close();
       
   475 	}
       
   476 
       
   477 EXPORT_C void RRemConPlayerListOfAttributes::Close()
       
   478 	{
       
   479 	iAttributes.Close();
       
   480 	}
       
   481 
       
   482 EXPORT_C void RRemConGetElementAttributesRequest::Close()
       
   483 	{
       
   484 	iAttributes.Close();
       
   485 	}
       
   486 
       
   487 EXPORT_C void RRemConPlayerAttributeIdsAndValues::Close()
       
   488 	{
       
   489 	iAttributeId.Close();
       
   490 	iAttributeValue.Close();
       
   491 	}
       
   492 
       
   493 EXPORT_C void RItem::Close()
       
   494 	{
       
   495 	delete iName;
       
   496 	for(TInt i = 0; i<iAttributes.Count(); i++)
       
   497 		{
       
   498 		iAttributes[i].Close();
       
   499 		}
       
   500 	}
       
   501 
       
   502 EXPORT_C TInt RItem::Size()
       
   503 	{
       
   504 	// Base size:
       
   505 	// type + length field + length
       
   506 	return 3 + iLength;
       
   507 	}
       
   508 
       
   509 EXPORT_C void RMediaPlayerItem::Close()
       
   510 	{
       
   511 	iName.Close();
       
   512 	}
       
   513 
       
   514 EXPORT_C TInt RMediaPlayerItem::Size()
       
   515 	{
       
   516 	// Base size:
       
   517 	// type + length field + length
       
   518 	return 3 + iLength;
       
   519 	}
       
   520 
       
   521 /**
       
   522 Parses PDU 0x74 and 0x90 requests.
       
   523 */
       
   524 EXPORT_C void RRemConNowPlayingRequest::ReadL(const TDesC8& aData)
       
   525 	{
       
   526 	iReadStream.Open(aData);
       
   527 	iScope = static_cast<TRemConFolderScope>(Read8L());
       
   528 	iElement = Read64L();
       
   529 	iUidCounter = Read16L();
       
   530 	}
       
   531 
       
   532 /**
       
   533 Constructs PDU 0x74 and 0x90 requests.
       
   534 */
       
   535 EXPORT_C void RRemConNowPlayingRequest::WriteL(TDes8& aOutData)
       
   536 	{
       
   537 	aOutData.Zero();
       
   538 	iStream.Open(aOutData);
       
   539 	Write32L(KErrNone);   // Successful operation
       
   540 	Write8L(iScope);
       
   541 	Write64L(iElement);
       
   542 	Write16L(iUidCounter);
       
   543 	iStream.CommitL();
       
   544 	}
       
   545 
       
   546 /**
       
   547 Parses PDU 0x74 and 0x90 responses
       
   548 */
       
   549 EXPORT_C void RRemConNowPlayingResponse::ReadL(const TDesC8& aData)
       
   550 	{
       
   551 	iReadStream.Open(aData);
       
   552 	iStatus = Read8L();
       
   553 	}
       
   554 
       
   555 /**
       
   556 Constructs PDU 0x74 and 0x90 responses.
       
   557 */
       
   558 EXPORT_C void RRemConNowPlayingResponse::WriteL(TDes8& aOutData)
       
   559 	{
       
   560 	aOutData.Zero();
       
   561 	iStream.Open(aOutData);
       
   562 	if ((KErrAvrcpAirBase - KErrAvrcpAirSuccess) == iStatus)
       
   563 	    {
       
   564 	    Write32L(KErrNone);   // Successful operation
       
   565 	    Write8L(iStatus);
       
   566 	    }
       
   567 	else
       
   568 		{
       
   569 		Write32L(KErrAvrcpAirBase - iStatus);
       
   570 		}
       
   571 	iStream.CommitL();
       
   572 	}
       
   573 
       
   574 // --------------------------------------------------------------------------------
       
   575 // Used for parsing PDU 0x71 requests
       
   576 EXPORT_C void RRemConGetFolderItemsRequest::ReadL(const TDesC8& aData)
       
   577 	{
       
   578 	iReadStream.Open(aData);
       
   579 	
       
   580 	iScope = Read8L();
       
   581 	iStartItem = Read32L();
       
   582 	iEndItem = Read32L();
       
   583 	iNumberAttributes = Read8L();
       
   584 	
       
   585 	if (iNumberAttributes == 0)
       
   586 		{
       
   587 		// spec says this is a request for all attribs
       
   588 		// current spec has 7 specified (0x01 to 0x07)
       
   589 		for (TInt i = 1; i <= KMaxMediaAttributeValue; i++)
       
   590 			{
       
   591 			iAttributes.AppendL(i);
       
   592 			}
       
   593 		}
       
   594 	else if (iNumberAttributes == 0xff)
       
   595 		{
       
   596 		// No attributes requested
       
   597 		}
       
   598 	else
       
   599 		{
       
   600 		for (TInt i = 0; i < iNumberAttributes; i++ )
       
   601 			{
       
   602 			TInt attribute = Read32L();
       
   603 			if (attribute > 0 && attribute <= KMaxMediaAttributeValue )
       
   604 				{
       
   605 				iAttributes.AppendL(attribute);
       
   606 				}
       
   607 			}
       
   608 		}
       
   609 
       
   610 	iReadStream.Close();
       
   611 	}
       
   612 
       
   613 EXPORT_C void RRemConGetFolderItemsRequest::WriteL(TDes8& aOutData)
       
   614 	{
       
   615 	aOutData.Zero();
       
   616 	iStream.Open(aOutData);
       
   617 	iAttributes.Sort();
       
   618 	Write32L(KErrNone);   // Successful operation
       
   619 	
       
   620 	Write8L(iScope);
       
   621 	Write32L(iStartItem);
       
   622 	Write32L(iEndItem);
       
   623 	Write8L(iNumberAttributes);
       
   624 
       
   625 	for (TInt i = 0; i < iNumberAttributes; i++ )
       
   626 		{
       
   627 		Write32L(iAttributes[i]);
       
   628 		}
       
   629 
       
   630 	iStream.CommitL();
       
   631 	}
       
   632 
       
   633 EXPORT_C void RRemConGetFolderItemsRequest::Close()
       
   634 	{
       
   635 	iAttributes.Close();
       
   636 	}
       
   637 
       
   638 EXPORT_C TInt RRemConGetFolderItemsRequest::CopyAttributes(RArray<TMediaAttributeId>& aOutAttributes)
       
   639 	{
       
   640 	TInt result = KErrNone;
       
   641 	TMediaAttributeId attributeId;
       
   642 	TInt attributeCount = iAttributes.Count();
       
   643 	for (TInt i = 0; i < attributeCount; i++)
       
   644 		{
       
   645 		attributeId = static_cast<TMediaAttributeId>(iAttributes[i]);
       
   646 		result = aOutAttributes.Append(attributeId);
       
   647 		if (result != KErrNone)
       
   648 			{
       
   649 			break;
       
   650 			}
       
   651 		}
       
   652 	return result;
       
   653 	}
       
   654 // --------------------------------------------------------------------------------
       
   655 // Used for PDU 0x71 responses
       
   656 
       
   657 EXPORT_C void RRemConGetFolderItemsResponse::ReadL(const TDesC8& aData)
       
   658 	{
       
   659 	iReadStream.Open(aData);
       
   660 	
       
   661 	iPduId = Read8L();
       
   662 	iParamLength = Read16L();
       
   663 	iStatus = Read8L();
       
   664 	iUidCounter = Read16L();
       
   665 	iNumberItems = Read16L();
       
   666 	
       
   667 	for(TInt i = 0; i < iNumberItems; i++)
       
   668 		{
       
   669 		ReadItemL();
       
   670 		}
       
   671 	
       
   672 	iReadStream.Close();
       
   673 	}
       
   674 
       
   675 void RRemConGetFolderItemsResponse::ReadItemL()
       
   676 	{
       
   677 	RItem item;
       
   678 	CleanupClosePushL(item);
       
   679 	
       
   680 	item.iType = static_cast<AvrcpBrowsing::TItemType>(Read8L());
       
   681 	item.iLength = Read16L();
       
   682 	item.iUid = Read64L();
       
   683 	
       
   684 	if(item.iType == AvrcpBrowsing::EFolderItem)
       
   685 		{
       
   686 		item.iFolderType = static_cast<AvrcpBrowsing::TFolderType>(Read8L());
       
   687 		item.iPlayable = Read8L();
       
   688 		}
       
   689 	else 
       
   690 		{
       
   691 		item.iMediaType = Read8L();
       
   692 		}
       
   693 	
       
   694 	item.iCharset = Read16L();
       
   695 	item.iNameLength = Read16L();
       
   696 	item.iName = HBufC8::NewL(item.iNameLength);
       
   697 	TPtr8 ptr = item.iName->Des();
       
   698 	iReadStream.ReadL(ptr);
       
   699 	
       
   700 	if(item.iType == AvrcpBrowsing::EMediaElement)
       
   701 		{
       
   702 		item.iNumberAttributes = Read32L();
       
   703 		
       
   704 		for (TInt i = 0; i < item.iNumberAttributes; i++ )
       
   705 			{
       
   706 			REAResponse eattr;
       
   707 			CleanupClosePushL(eattr);
       
   708 			
       
   709 			eattr.iAttributeId = Read32L();
       
   710 			eattr.iCharset     = Read16L();
       
   711 			eattr.iStringLen   = Read16L();
       
   712 			eattr.iString      = HBufC8::NewL(eattr.iStringLen);
       
   713 			TPtr8 ptr          = eattr.iString->Des();
       
   714 			iReadStream.ReadL(ptr);
       
   715 			
       
   716 			item.iAttributes.AppendL(eattr);
       
   717 			CleanupStack::Pop(&eattr);
       
   718 			}
       
   719 		}
       
   720 	
       
   721 	iItems.AppendL(item);
       
   722 	CleanupStack::Pop(&item);
       
   723 	}
       
   724 
       
   725 EXPORT_C void RRemConGetFolderItemsResponse::WriteL(TDes8& aOutData)
       
   726 	{
       
   727 	__ASSERT_DEBUG(aOutData.MaxLength() >= Size(), AvrcpIpcUtils::Panic(EAvrcpIpcCommandDataTooLong));
       
   728 	aOutData.Zero();
       
   729 	iStream.Open(aOutData);
       
   730 	
       
   731 	Write8L(iPduId);
       
   732 	Write16L(iParamLength);
       
   733 	Write8L(iStatus);
       
   734 	
       
   735 	if(iStatus == 0x4)
       
   736 		{
       
   737 		Write16L(iUidCounter);
       
   738 		Write16L(iNumberItems);
       
   739 	
       
   740 		for (TInt i = 0; i < iNumberItems; i++ )
       
   741 			{
       
   742 			WriteItemL(i);
       
   743 			}
       
   744 		}
       
   745 	
       
   746 	iStream.CommitL();
       
   747 	}
       
   748 
       
   749 void RRemConGetFolderItemsResponse::WriteItemL(TInt aIndex)
       
   750 	{
       
   751 	RItem& item = iItems[aIndex];
       
   752 	
       
   753 	Write8L(item.iType);
       
   754 	Write16L(item.iLength);
       
   755 	Write64L(item.iUid);
       
   756 	
       
   757 	if(item.iType == AvrcpBrowsing::EFolderItem)
       
   758 		{
       
   759 		Write8L(item.iFolderType);
       
   760 		Write8L(item.iPlayable);
       
   761 		}
       
   762 	else
       
   763 		{
       
   764 		Write8L(item.iMediaType);
       
   765 		}
       
   766 	
       
   767 	Write16L(item.iCharset);
       
   768 	Write16L(item.iNameLength);
       
   769 	iStream.WriteL(item.iName->Des());
       
   770 	
       
   771 	if(item.iType == AvrcpBrowsing::EMediaElement)
       
   772 		{
       
   773 		Write8L(item.iNumberAttributes);
       
   774 		
       
   775 		for(TInt i = 0; i < item.iNumberAttributes; i++)
       
   776 			{
       
   777 			Write32L(item.iAttributes[i].iAttributeId);
       
   778 			Write16L(item.iAttributes[i].iCharset);
       
   779 			Write16L(item.iAttributes[i].iStringLen);
       
   780 			iStream.WriteL(item.iAttributes[i].iString->Des());
       
   781 			}
       
   782 		}
       
   783 	}
       
   784 
       
   785 EXPORT_C TInt RRemConGetFolderItemsResponse::Size()
       
   786 	{
       
   787 	// Return the size that a buffer needs to be allocated to
       
   788 	// serialise the data encapsulated within this data structure.
       
   789 	
       
   790 	// base size 
       
   791 	// pduid + paramlength + status + uidcount + number items
       
   792 	TInt size = KGetFolderItemsResponseBaseSize;
       
   793 	
       
   794 	for (TInt i = 0; i < iNumberItems; i++)
       
   795 		{
       
   796 		size += iItems[i].Size();
       
   797 		}
       
   798 	return size;
       
   799 	}
       
   800 
       
   801 EXPORT_C void RRemConGetFolderItemsResponse::Close()
       
   802 	{
       
   803 	for (TInt i = 0; i < iItems.Count(); i++)
       
   804 		{
       
   805 		iItems[i].Close();
       
   806 		}
       
   807 	iItems.Reset();
       
   808 	}
       
   809 
       
   810 EXPORT_C TInt RRemConGetFolderItemsResponse::CopyItems(
       
   811 		const TArray<TRemConItem>& aItems)
       
   812 	{
       
   813 	TInt err = KErrNone;
       
   814 	for(TInt i = 0; i < aItems.Count(); i++)
       
   815 		{
       
   816 		RItem item;
       
   817 		item.iName = NULL;
       
   818 		item.iUid = aItems[i].iUid;
       
   819 		item.iType = static_cast<AvrcpBrowsing::TItemType>(aItems[i].iType);
       
   820 		
       
   821 		err = iItems.Append(item);
       
   822 		if(err)
       
   823 			{
       
   824 			break;
       
   825 			}
       
   826 		}
       
   827 	return err;
       
   828 	}
       
   829 
       
   830 EXPORT_C TBool RRemConGetFolderItemsResponse::RequestNextItem(TInt& aError, 
       
   831 		RBuf8& aOutBuf, TUint16 aCookie)
       
   832 	{
       
   833 	aError = KErrNone;
       
   834 	// Work out if we have as many items as fit
       
   835 	TBool getMoreItems = ETrue;
       
   836 	iCurrentListingSize += (iCurrentItem + 1) ? iItems[iCurrentItem].Size() : 0;
       
   837 	if(iCurrentListingSize > iMaxResponse)
       
   838 		{
       
   839 		// We can't fit this item in the listing
       
   840 		iItems[iCurrentItem].Close();
       
   841 		getMoreItems = EFalse;
       
   842 		iItems.Remove(iCurrentItem);
       
   843 		}
       
   844 	
       
   845 	if(getMoreItems && ++iCurrentItem < iItems.Count())
       
   846 		{
       
   847 		return ETrue;
       
   848 		}
       
   849 	else
       
   850 		{
       
   851 		// We have all items, send the response
       
   852 		iNumberItems = iCurrentItem;
       
   853 		if(aOutBuf.Create(Size()) != KErrNone)
       
   854 			{
       
   855 			aError = KErrGeneral;
       
   856 			return EFalse;
       
   857 			}
       
   858 		
       
   859 		iPduId = AvrcpBrowsing::EGetFolderItems;
       
   860 		iStatus = KErrAvrcpAirBase - KErrAvrcpAirSuccess;//0x4
       
   861 		iUidCounter = aCookie;
       
   862 		TRAP(aError, WriteL(aOutBuf));
       
   863 		}
       
   864 	return EFalse;
       
   865 	}
       
   866 // --------------------------------------------------------------------------------
       
   867 // Used for parsing PDU 0x72 requests
       
   868 
       
   869 EXPORT_C void RRemConChangePathRequest::ReadL(const TDesC8& aData)
       
   870 	{
       
   871 	iReadStream.Open(aData);
       
   872 	
       
   873 	iUidCounter = Read16L();
       
   874 	iDirection = Read8L();
       
   875 	
       
   876 	if(iDirection == AvrcpBrowsing::KDown)
       
   877 		{
       
   878 		iElement = Read64L();
       
   879 		}
       
   880 
       
   881 	iReadStream.Close();
       
   882 	}
       
   883 
       
   884 EXPORT_C void RRemConChangePathRequest::WriteL(TDes8& aOutData)
       
   885 	{
       
   886 	aOutData.Zero();
       
   887 	iStream.Open(aOutData);
       
   888 	
       
   889 	Write16L(iUidCounter);
       
   890 	Write8L(iDirection);
       
   891 	Write64L(iElement);
       
   892 
       
   893 	iStream.CommitL();
       
   894 	}
       
   895 
       
   896 // --------------------------------------------------------------------------------
       
   897 // Used for PDU 0x72 responses
       
   898 
       
   899 EXPORT_C void RRemConChangePathResponse::ReadL(const TDesC8& aData)
       
   900 	{
       
   901 	iReadStream.Open(aData);
       
   902 	
       
   903 	iStatus = Read8L();
       
   904 	iNumberItems = Read32L();
       
   905 	
       
   906 	iReadStream.Close();
       
   907 	}
       
   908 
       
   909 EXPORT_C void RRemConChangePathResponse::WriteL(TDes8& aOutData)
       
   910 	{
       
   911 	aOutData.Zero();
       
   912 	iStream.Open(aOutData);
       
   913 	
       
   914 	Write8L(iPduId);
       
   915 	Write16L(iParamLength);
       
   916 	Write8L(iStatus);
       
   917 	
       
   918 	if(iStatus == 0x4)
       
   919 		{
       
   920 		Write32L(iNumberItems);
       
   921 		}
       
   922 		
       
   923 	iStream.CommitL();
       
   924 	}
       
   925 
       
   926 // --------------------------------------------------------------------------------
       
   927 // Used for parsing PDU 0x73 requests
       
   928 
       
   929 EXPORT_C void RRemConGetItemAttributesRequest::ReadL(const TDesC8& aData)
       
   930 	{
       
   931 	iReadStream.Open(aData);
       
   932 	
       
   933 	iScope = Read8L();
       
   934 	iElement = Read64L();
       
   935 	iUidCounter = Read16L();
       
   936 	iNumberAttributes = Read8L();
       
   937 	
       
   938 	for (TInt i = 0; i < iNumberAttributes; i++ )
       
   939 		{
       
   940 		TInt attribute = Read32L();
       
   941 		iAttributes.AppendL(attribute);
       
   942 		}
       
   943 	
       
   944 	iReadStream.Close();
       
   945 	}
       
   946 
       
   947 EXPORT_C void RRemConGetItemAttributesRequest::WriteL(TDes8& aOutData)
       
   948 	{
       
   949 	aOutData.Zero();
       
   950 	iStream.Open(aOutData);
       
   951 	iAttributes.Sort();
       
   952 	Write32L(KErrNone);   // Successful operation
       
   953 	
       
   954 	Write8L(iScope);
       
   955 	// 64 bits of data
       
   956 	Write64L(iElement);
       
   957 	Write16L(iUidCounter);
       
   958 	Write8L(iNumberAttributes);
       
   959 
       
   960 	for (TInt i = 0; i < iNumberAttributes; i++ )
       
   961 		{
       
   962 		Write32L(iAttributes[i]);
       
   963 		}
       
   964 	iStream.CommitL();
       
   965 	}
       
   966 
       
   967 EXPORT_C void RRemConGetItemAttributesRequest::Close()
       
   968 	{
       
   969 	iAttributes.Close();
       
   970 	}
       
   971 
       
   972 // --------------------------------------------------------------------------------
       
   973 // Used for PDU 0x73 responses
       
   974 
       
   975 EXPORT_C void RRemConGetItemAttributesResponse::ReadL(const TDesC8& aData)
       
   976 	{
       
   977 	iReadStream.Open(aData);
       
   978 	
       
   979 	iStatus = Read8L();
       
   980 	iNumberAttributes = Read8L();
       
   981 	
       
   982 	for (TInt i = 0; i < iNumberAttributes; i++ )
       
   983 		{
       
   984 		REAResponse eattr;
       
   985 		eattr.iAttributeId = Read32L();
       
   986 		eattr.iCharset     = Read16L();
       
   987 		eattr.iStringLen   = Read16L();
       
   988 		eattr.iString      = HBufC8::NewL(eattr.iStringLen);
       
   989 		TPtr8 ptr          = eattr.iString->Des();
       
   990 		iReadStream.ReadL(ptr);
       
   991 		iAttributes.AppendL(eattr);
       
   992 		}
       
   993 	iReadStream.Close();
       
   994 	}
       
   995 
       
   996 EXPORT_C void RRemConGetItemAttributesResponse::WriteL(TDes8& aOutData)
       
   997 	{
       
   998 	aOutData.Zero();
       
   999 	iStream.Open(aOutData);
       
  1000 	
       
  1001 	Write8L(iPduId);
       
  1002 	Write16L(iParamLength);
       
  1003 	Write8L(iStatus);
       
  1004 	
       
  1005 	if(iStatus == 0x4)
       
  1006 		{
       
  1007 		Write8L(iNumberAttributes);
       
  1008 	
       
  1009 		for (TInt i = 0; i < iNumberAttributes; i++ )
       
  1010 			{
       
  1011 			Write32L(iAttributes[i].iAttributeId);
       
  1012 			Write16L(iAttributes[i].iCharset);
       
  1013 			Write16L(iAttributes[i].iStringLen);
       
  1014 			iStream.WriteL(iAttributes[i].iString->Des());
       
  1015 			}
       
  1016 		}
       
  1017 	iStream.CommitL();
       
  1018 	}
       
  1019 
       
  1020 EXPORT_C TInt RRemConGetItemAttributesResponse::Size()
       
  1021 	{
       
  1022 	// Return the size that a buffer needs to be allocated to
       
  1023 	// serialise the data encapsulated within this data structure.
       
  1024 	
       
  1025 	TInt size = 9; // 6 bytes: error + pduid + paramlength + status code + number attributes
       
  1026 	for (TInt i = 0; i < iAttributes.Count(); i++)
       
  1027 		{
       
  1028 		size += 4+2+2; // 8 bytes: attrId (4 bytes) + charset (2 bytes) + stringlen (2 bytes)
       
  1029 		size += iAttributes[i].iString->Length();
       
  1030 		}
       
  1031 	return size;
       
  1032 	}
       
  1033 
       
  1034 EXPORT_C void RRemConGetItemAttributesResponse::Close()
       
  1035 	{
       
  1036 	for (TInt i = 0; i < iAttributes.Count(); i++)
       
  1037 		{
       
  1038 		iAttributes[i].Close();
       
  1039 		}
       
  1040 	iAttributes.Close();
       
  1041 	}
       
  1042 
       
  1043 // --------------------------------------------------------------------------------
       
  1044 // Used for parsing PDU 0x80 requests
       
  1045 
       
  1046 EXPORT_C void RRemConSearchRequest::ReadL(const TDesC8& aData)
       
  1047 	{
       
  1048 	iReadStream.Open(aData);
       
  1049 	
       
  1050 	iCharset = Read16L();
       
  1051 	iStringLen = Read16L();
       
  1052 	
       
  1053 	TInt dataLength = aData.Length();
       
  1054 	TPtrC8 pString = aData.Right(dataLength - 2*sizeof(TUint16));
       
  1055 	if (pString.Length() != iStringLen)
       
  1056 		{
       
  1057 		User::Leave(KErrArgument);
       
  1058 		}
       
  1059 	
       
  1060 	RBuf8 searchBuf;
       
  1061 	searchBuf.CreateL(iStringLen);
       
  1062 	CleanupClosePushL(searchBuf);
       
  1063 	
       
  1064 	iReadStream.ReadL(searchBuf);
       
  1065 	
       
  1066 	CleanupStack::Pop(&searchBuf);
       
  1067 	iSearchString.Assign(searchBuf);
       
  1068 
       
  1069 	iReadStream.Close();
       
  1070 	}
       
  1071 
       
  1072 EXPORT_C void RRemConSearchRequest::WriteL(TDes8& aOutData)
       
  1073 	{
       
  1074 	aOutData.Zero();
       
  1075 	iStream.Open(aOutData);
       
  1076 	
       
  1077 	Write16L(iCharset);
       
  1078 	Write16L(iStringLen);
       
  1079 	WriteL(iSearchString);
       
  1080 	
       
  1081 	iStream.CommitL();
       
  1082 	}
       
  1083 
       
  1084 EXPORT_C TInt RRemConSearchRequest::Size()
       
  1085 	{
       
  1086 	// Return the size that a buffer needs to be allocated to
       
  1087 	// serialise the data encapsulated within this data structure.
       
  1088 	TInt size = sizeof(iCharset) + sizeof(iStringLen) + iSearchString.Length(); 
       
  1089 	
       
  1090 	return size;
       
  1091 	}
       
  1092 
       
  1093 EXPORT_C void RRemConSearchRequest::Close()
       
  1094 	{
       
  1095 	iSearchString.Close();
       
  1096 	}
       
  1097 
       
  1098 // --------------------------------------------------------------------------------
       
  1099 // Used for PDU 0x80 responses
       
  1100 
       
  1101 EXPORT_C void RRemConSearchResponse::ReadL(const TDesC8& aData)
       
  1102 	{
       
  1103 	iReadStream.Open(aData);
       
  1104 	
       
  1105 	iStatus = Read8L();
       
  1106 	iUidCounter = Read16L();
       
  1107 	iNumberItems = Read32L();
       
  1108 	
       
  1109 	iReadStream.Close();
       
  1110 	}
       
  1111 
       
  1112 EXPORT_C void RRemConSearchResponse::WriteL(TDes8& aOutData)
       
  1113 	{
       
  1114 	aOutData.Zero();
       
  1115 	iStream.Open(aOutData);
       
  1116 	
       
  1117 	Write8L(iPduId);
       
  1118 	Write16L(iParamLength);
       
  1119 	Write8L(iStatus);
       
  1120 	
       
  1121 	if(iStatus == 0x4)
       
  1122 		{
       
  1123 		Write16L(iUidCounter);
       
  1124 		Write32L(iNumberItems);
       
  1125 		}
       
  1126 
       
  1127 	iStream.CommitL();
       
  1128 	}
       
  1129 
       
  1130 // --------------------------------------------------------------------------------
       
  1131 // Used for parsing SetBrowsedPlayer requests
       
  1132 
       
  1133 EXPORT_C void RRemConSetBrowsedPlayerRequest::ReadL(const TDesC8& aData)
       
  1134 	{
       
  1135 	iReadStream.Open(aData);
       
  1136 	
       
  1137 	// iMaxResponse is little endian
       
  1138 	iMaxResponse = iReadStream.ReadInt32L();
       
  1139 	iPlayerId = Read16L();
       
  1140 	
       
  1141 	iReadStream.Close();
       
  1142 	}
       
  1143 
       
  1144 EXPORT_C void RRemConSetBrowsedPlayerRequest::WriteL(TDes8& aOutData)
       
  1145 	{
       
  1146 	aOutData.Zero();
       
  1147 	iStream.Open(aOutData);
       
  1148 	
       
  1149 	// Use little endian on iMaxResponse
       
  1150 	iStream.WriteInt32L(iMaxResponse);
       
  1151 	Write16L(iPlayerId);
       
  1152 	
       
  1153 	iStream.CommitL();
       
  1154 	}
       
  1155 
       
  1156 // --------------------------------------------------------------------------------
       
  1157 // Used for SetBrowsedPlayer responses
       
  1158 
       
  1159 EXPORT_C void RRemConGetPathResponse::ReadL(const TDesC8& aData)
       
  1160 	{
       
  1161 	iReadStream.Open(aData);
       
  1162 	
       
  1163 	iStatus = Read8L();
       
  1164 	iUidCounter = Read16L();
       
  1165 	iNumberItems = Read32L();
       
  1166 	
       
  1167 	iReadStream.Close();
       
  1168 	}
       
  1169 
       
  1170 EXPORT_C void RRemConGetPathResponse::WriteL(TDes8& aOutData)
       
  1171 	{
       
  1172 	aOutData.Zero();
       
  1173 	iStream.Open(aOutData);
       
  1174 	
       
  1175 	Write8L(iPduId);
       
  1176 	Write16L(iParamLength);
       
  1177 	Write8L(iStatus);
       
  1178 	
       
  1179 	if(iStatus != 0x4)
       
  1180 		{
       
  1181 		iStream.CommitL();
       
  1182 		return;
       
  1183 		}
       
  1184     
       
  1185 	// The depth is equal to the number of items in the array.
       
  1186 	iFolderDepth = iPath.Count();
       
  1187 	Write16L(iUidCounter);
       
  1188 	Write32L(iNumberItems);
       
  1189 	Write16L(KUtf8MibEnum);
       
  1190 	Write8L(iFolderDepth);
       
  1191 	
       
  1192 	for(TInt i = 0; i < iFolderDepth; i++)
       
  1193 		{
       
  1194 		Write16L((iPath[i])->Length());
       
  1195 		iStream.WriteL(*(iPath[i]));
       
  1196 		}
       
  1197 	
       
  1198 	iStream.CommitL();
       
  1199 	}
       
  1200 
       
  1201 EXPORT_C TInt RRemConGetPathResponse::Size()
       
  1202 	{
       
  1203 	// Return the size that a buffer needs to be allocated to
       
  1204 	// serialise the data encapsulated within this data structure.
       
  1205 	iFolderDepth = iPath.Count();
       
  1206 	TInt size = 13 + (iFolderDepth*2);
       
  1207 	
       
  1208 	for(TInt i = 0; i < iFolderDepth; i++)
       
  1209 		{
       
  1210 		size += (iPath[i])->Length();
       
  1211 		}
       
  1212 	
       
  1213 	return size;
       
  1214 	}
       
  1215 
       
  1216 EXPORT_C void RRemConGetPathResponse::Close()
       
  1217 	{
       
  1218 	iPath.ResetAndDestroy();
       
  1219 	}
       
  1220 
       
  1221 // --------------------------------------------------------------------------------
       
  1222 // Used for parsing SetAddressedPlayer requests
       
  1223 
       
  1224 EXPORT_C void RAvrcpSetAddressedPlayerRequest::ReadL(const TDesC8& aData)
       
  1225 	{
       
  1226 	iReadStream.Open(aData);
       
  1227 	
       
  1228 	iPlayerId = Read16L();
       
  1229 	
       
  1230 	iReadStream.Close();
       
  1231 	}
       
  1232 
       
  1233 EXPORT_C void RAvrcpSetAddressedPlayerRequest::WriteL(TDes8& aOutData)
       
  1234 	{
       
  1235 	aOutData.Zero();
       
  1236 	iStream.Open(aOutData);
       
  1237 	
       
  1238 	Write16L(iPlayerId);
       
  1239 	
       
  1240 	iStream.CommitL();
       
  1241 	}
       
  1242 
       
  1243 // --------------------------------------------------------------------------------
       
  1244 // Used for SetAddressedPlayer responses
       
  1245 
       
  1246 EXPORT_C void RAvrcpSetAddressedPlayerResponse::ReadL(const TDesC8& aData)
       
  1247 	{
       
  1248 	iReadStream.Open(aData);
       
  1249 	
       
  1250 	iStatus = Read8L();
       
  1251 	
       
  1252 	iReadStream.Close();
       
  1253 	}
       
  1254 
       
  1255 EXPORT_C void RAvrcpSetAddressedPlayerResponse::WriteL(TDes8& aOutData)
       
  1256 	{
       
  1257 	aOutData.Zero();
       
  1258 	iStream.Open(aOutData);
       
  1259 	
       
  1260 	Write32L(KErrNone);   // Successful operation
       
  1261 	Write8L(iStatus);
       
  1262 	
       
  1263 	iStream.CommitL();
       
  1264 	}
       
  1265 
       
  1266 // --------------------------------------------------------------------------------
       
  1267 // Used for parsing PDU 0x71 requests with media player list scope
       
  1268 
       
  1269 EXPORT_C void RAvrcpGetFolderItemsRequest::ReadL(const TDesC8& aData)
       
  1270 	{
       
  1271 	iReadStream.Open(aData);
       
  1272 	
       
  1273 	iScope = Read8L();
       
  1274 	iStartItem = Read32L();
       
  1275 	iEndItem = Read32L();
       
  1276 	}
       
  1277 
       
  1278 EXPORT_C void RAvrcpGetFolderItemsRequest::WriteL(TDes8& aOutData)
       
  1279 	{
       
  1280 	aOutData.Zero();
       
  1281 	iStream.Open(aOutData);
       
  1282 	Write32L(KErrNone);   // Successful operation
       
  1283 	
       
  1284 	Write8L(iScope);
       
  1285 	Write32L(iStartItem);
       
  1286 	Write32L(iEndItem);
       
  1287 
       
  1288 	iStream.CommitL();
       
  1289 	}
       
  1290 
       
  1291 EXPORT_C void RAvrcpGetFolderItemsRequest::Close()
       
  1292 	{
       
  1293 	RAvrcpIPC::Close();
       
  1294 	}
       
  1295 
       
  1296 // --------------------------------------------------------------------------------
       
  1297 // Used for PDU 0x71 responses with media player list scope
       
  1298 
       
  1299 EXPORT_C void RAvrcpGetFolderItemsResponse::ReadL(const TDesC8& aData)
       
  1300 	{
       
  1301 	iReadStream.Open(aData);
       
  1302 	
       
  1303 	iPduId = Read8L();
       
  1304 	iParamLength = Read16L();
       
  1305 	iStatus = Read8L();
       
  1306 	iUidCounter = Read16L();
       
  1307 	iNumberItems = Read16L();
       
  1308 	
       
  1309 	for(TInt i = 0; i < iNumberItems; i++)
       
  1310 		{
       
  1311 		ReadItemL();
       
  1312 		}
       
  1313 	
       
  1314 	iReadStream.Close();
       
  1315 	}
       
  1316 
       
  1317 void RAvrcpGetFolderItemsResponse::ReadItemL()
       
  1318 	{
       
  1319 	RMediaPlayerItem item;
       
  1320 	CleanupClosePushL(item);
       
  1321 	
       
  1322 	item.iType = static_cast<AvrcpBrowsing::TItemType>(Read8L());
       
  1323 	item.iLength = Read16L();
       
  1324 	item.iPlayerId = Read16L();
       
  1325 	
       
  1326 	item.iPlayerType = Read8L();
       
  1327 	item.iPlayerSubType = Read32L();
       
  1328 	item.iPlayStatus = Read8L();
       
  1329 	iReadStream.ReadL(item.iFeatureBitmask);
       
  1330 	
       
  1331 	item.iCharset = Read16L();
       
  1332 	item.iNameLength = Read16L();
       
  1333 	
       
  1334 	item.iName.CreateL(item.iNameLength);
       
  1335 	iReadStream.ReadL(item.iName);
       
  1336 	
       
  1337 	iItems.AppendL(item);
       
  1338 	CleanupStack::Pop(&item);
       
  1339 	}
       
  1340 
       
  1341 EXPORT_C void RAvrcpGetFolderItemsResponse::WriteL(TDes8& aOutData)
       
  1342 	{
       
  1343 	__ASSERT_DEBUG(aOutData.MaxLength() >= Size(), AvrcpIpcUtils::Panic(EAvrcpIpcCommandDataTooLong));
       
  1344 	aOutData.Zero();
       
  1345 	iStream.Open(aOutData);
       
  1346 	
       
  1347 	Write8L(iPduId);
       
  1348 	Write16L(iParamLength);
       
  1349 	Write8L(iStatus);
       
  1350 	
       
  1351 	if(iStatus == 0x4)
       
  1352 		{
       
  1353 		Write16L(iUidCounter);
       
  1354 		Write16L(iNumberItems);
       
  1355 	
       
  1356 		for (TInt i = 0; i < iNumberItems; i++ )
       
  1357 			{
       
  1358 			WriteItemL(i);
       
  1359 			}
       
  1360 		}
       
  1361 	
       
  1362 	iStream.CommitL();
       
  1363 	}
       
  1364 
       
  1365 void RAvrcpGetFolderItemsResponse::WriteItemL(TInt aIndex)
       
  1366 	{
       
  1367 	RMediaPlayerItem& item = iItems[aIndex];
       
  1368 	
       
  1369 	Write8L(item.iType);
       
  1370 	Write16L(item.iLength);
       
  1371 	Write16L(item.iPlayerId);
       
  1372 	
       
  1373 	Write8L(item.iPlayerType);
       
  1374 	Write32L(item.iPlayerSubType);
       
  1375 	Write8L(item.iPlayStatus);
       
  1376 	iStream.WriteL(item.iFeatureBitmask);
       
  1377 	
       
  1378 	Write16L(item.iCharset);
       
  1379 	Write16L(item.iNameLength);
       
  1380 	iStream.WriteL(item.iName);
       
  1381 	}
       
  1382 
       
  1383 EXPORT_C TInt RAvrcpGetFolderItemsResponse::Size()
       
  1384 	{
       
  1385 	// Return the size that a buffer needs to be allocated to
       
  1386 	// serialise the data encapsulated within this data structure.
       
  1387 	
       
  1388 	// base size 
       
  1389 	// pduid + paramlength + status + uidcount + number items
       
  1390 	TInt size = KGetFolderItemsResponseBaseSize;
       
  1391 	
       
  1392 	for (TInt i = 0; i < iNumberItems; i++)
       
  1393 		{
       
  1394 		size += iItems[i].Size();
       
  1395 		}
       
  1396 	return size;
       
  1397 	}
       
  1398 
       
  1399 EXPORT_C void RAvrcpGetFolderItemsResponse::Close()
       
  1400 	{
       
  1401 	for (TInt i = 0; i < iNumberItems; i++)
       
  1402 		{
       
  1403 		iItems[i].Close();
       
  1404 		}
       
  1405 	iItems.Reset();
       
  1406 	}
       
  1407 
       
  1408 // --------------------------------------------------------------------------------
       
  1409 // Used for PDU 0x30 responses with event addressed player changed
       
  1410 
       
  1411 EXPORT_C void RAvrcpAddressedPlayerNotificationResponse::ReadL(const TDesC8& aData)
       
  1412 	{
       
  1413 	iReadStream.Open(aData);
       
  1414 	iPlayerId = Read16L();
       
  1415 	iUidCounter = Read16L();
       
  1416 	iReadStream.Close();
       
  1417 	}
       
  1418 
       
  1419 EXPORT_C void RAvrcpAddressedPlayerNotificationResponse::WriteL(TDes8& aOutData)
       
  1420 	{
       
  1421 	aOutData.Zero();
       
  1422 	iStream.Open(aOutData);
       
  1423 	Write32L(KErrNone);   // Successful operation
       
  1424 	
       
  1425 	Write16L(iPlayerId);
       
  1426 	Write16L(iUidCounter);
       
  1427 	iStream.CommitL();
       
  1428 	}
       
  1429 
       
  1430 EXPORT_C void RAvrcpUidCounterNotificationResponse::ReadL(const TDesC8& aData)
       
  1431 	{
       
  1432 	iReadStream.Open(aData);
       
  1433 	iUidCounter = Read16L();
       
  1434 	iReadStream.Close();
       
  1435 	}
       
  1436 
       
  1437 EXPORT_C void RAvrcpUidCounterNotificationResponse::WriteL(TDes8& aOutData)
       
  1438 	{
       
  1439 	aOutData.Zero();
       
  1440 	iStream.Open(aOutData);
       
  1441 	Write32L(KErrNone);   // Successful operation
       
  1442 	
       
  1443 	Write16L(iUidCounter);
       
  1444 	iStream.CommitL();
       
  1445 	}
       
  1446 
       
  1447 EXPORT_C void RRemConMediaErrorResponse::ReadL(const TDesC8& aData)
       
  1448 	{
       
  1449 	iReadStream.Open(aData);
       
  1450 	iPduId = Read8L();
       
  1451 	iLength = Read16L();
       
  1452 	iStatus = Read8L();
       
  1453 	iReadStream.Close();
       
  1454 	}
       
  1455 
       
  1456 EXPORT_C void RRemConMediaErrorResponse::WriteL(TDes8& aOutData)
       
  1457 	{
       
  1458 	aOutData.Zero();
       
  1459 	iStream.Open(aOutData);
       
  1460 	Write8L(iPduId);
       
  1461 	Write16L(KErrResponseParameterLength);
       
  1462 	Write8L(iStatus);
       
  1463 	iStream.CommitL();
       
  1464 	}
       
  1465 
       
  1466 EXPORT_C TUint8 RAvrcpIPC::SymbianErrToStatus(TInt aErr)
       
  1467 	{
       
  1468 	return KErrAvrcpAirBase - SymbianErrorCheck(aErr);
       
  1469 	}
       
  1470 
       
  1471 /**
       
  1472 Ensure we get a known error.
       
  1473 */
       
  1474 EXPORT_C TInt RAvrcpIPC::SymbianErrorCheck(TInt aError)
       
  1475 	{
       
  1476 	TInt error = aError;
       
  1477 	
       
  1478 	switch (error)
       
  1479 		{
       
  1480 		case KErrNone:
       
  1481 			error = KErrAvrcpAirSuccess;
       
  1482 			break;
       
  1483 		case KErrAvrcpAirInvalidCommand:
       
  1484 		case KErrAvrcpAirInvalidParameter:
       
  1485 		case KErrAvrcpAirParameterNotFound:
       
  1486 		case KErrAvrcpAirInternalError:
       
  1487 		case KErrAvrcpAirSuccess:
       
  1488 		case KErrAvrcpAirUidChanged:
       
  1489 		case KErrAvrcpAirReserved:
       
  1490 		case KErrAvrcpAirInvalidDirection:
       
  1491 		case KErrAvrcpAirNotADirectory:
       
  1492 		case KErrAvrcpAirDoesNotExist:
       
  1493 		case KErrAvrcpAirInvalidScope:
       
  1494 		case KErrAvrcpAirRangeOutOfBounds:
       
  1495 		case KErrAvrcpAirUidIsADirectory:
       
  1496 		case KErrAvrcpAirMediaInUse:
       
  1497 		case KErrAvrcpAirNowPlayingListFull:
       
  1498 		case KErrAvrcpAirSearchNotSupported:
       
  1499 		case KErrAvrcpAirSearchInProgress:
       
  1500 		case KErrAvrcpAirInvalidPlayerId:
       
  1501 		case KErrAvrcpAirPlayerNotBrowesable:
       
  1502 		case KErrAvrcpAirPlayerNotAddressed:
       
  1503 		case KErrAvrcpAirNoValidSearchResults:
       
  1504 		case KErrAvrcpAirNoAvailablePlayers:
       
  1505 		case KErrAvrcpAirAddressedPlayerChanged:
       
  1506 		case KErrAvrcpInvalidScope:
       
  1507 			break;
       
  1508 		default:
       
  1509 			error = KErrAvrcpAirInternalError;
       
  1510 		}
       
  1511 	
       
  1512 	return error;
       
  1513 	}
       
  1514 
       
  1515 EXPORT_C void RRemConUidsChangedRequest::ReadL(const TDesC8& aData)
       
  1516 	{
       
  1517 	iReadStream.Open(aData);
       
  1518 	iInitialUidCounter = Read16L();
       
  1519 	}
       
  1520 
       
  1521 EXPORT_C void RRemConUidsChangedRequest::WriteL(TDes8& aOutData)
       
  1522 	{
       
  1523 	aOutData.Zero();
       
  1524 	iStream.Open(aOutData);
       
  1525 	Write16L(iInitialUidCounter);
       
  1526 	iStream.CommitL();
       
  1527 	}
       
  1528 
       
  1529 EXPORT_C void RRemConUidsChangedResponse::ReadL(const TDesC8& aData)
       
  1530 	{
       
  1531 	iReadStream.Open(aData);
       
  1532 	iUidCounter = Read16L();
       
  1533 	}
       
  1534 
       
  1535 EXPORT_C void RRemConUidsChangedResponse::WriteL(TDes8& aOutData)
       
  1536 	{
       
  1537 	aOutData.Zero();
       
  1538 	iStream.Open(aOutData);
       
  1539 	Write16L(iUidCounter);
       
  1540 	iStream.CommitL();
       
  1541 	}