contentmgmt/cafstreamingsupport/test/streamingtestagent/source/server/stasession.cpp
branchRCL_3
changeset 43 2f10d260163b
child 61 641f389e9157
equal deleted inserted replaced
42:eb9b28acd381 43:2f10d260163b
       
     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 the License "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 // Implements CStaSession which is server-side session object.
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "staserver.h"
       
    19 #include "srautils.h"
       
    20 
       
    21 using namespace StreamAccess;
       
    22 using namespace ContentAccess;
       
    23 
       
    24 CStaSession::CStaSession(CStaServer& aServer)
       
    25 /**
       
    26 	Intializes the Streaming Test Agent session object with the server handle.
       
    27  */
       
    28 	:	CScsSession(aServer)
       
    29 		{
       
    30 		//empty
       
    31 		}
       
    32 
       
    33 
       
    34 CStaSession::~CStaSession()
       
    35 /**
       
    36 	Destructor.
       
    37  */
       
    38 	{
       
    39 	delete iBuffer;	
       
    40 	delete iKeyStreamSink;
       
    41 	delete iRo;
       
    42 #ifdef INTERNALLY_ENABLE_UPWARD_DEPENDENCY
       
    43 	delete iSdp;
       
    44 	delete iSdpDoc;
       
    45 #endif
       
    46 	}
       
    47 
       
    48 	
       
    49 CStaSession* CStaSession::NewL(CStaServer& aServer)
       
    50 /**
       
    51 	Factory function allocates new instance of CStaSession.
       
    52 	
       
    53 	@param aServer  Streaming Test Agent server object.
       
    54 	@return			New, initialized instance of CStaSession 
       
    55 					which is owned by the caller.
       
    56  */
       
    57 	{
       
    58 	CStaSession* s = new (ELeave) CStaSession(aServer);
       
    59 	CleanupStack::PushL(s);
       
    60 	s->ConstructL();
       
    61 	CleanupStack::Pop(s);
       
    62 	return s;
       
    63 	}
       
    64 
       
    65 
       
    66 TBool CStaSession::DoServiceL(TInt aFunction, const RMessage2& aMessage)
       
    67 /**
       
    68 	Implement CScsSession by handling the supplied message.
       
    69 
       
    70 	@param	aFunction	Function identifier without SCS code.
       
    71 	@param	aMessage	Standard server-side handle to message.
       
    72 	@return 			ETrue, if the service is done successfully. Otherwise, EFalse.
       
    73  */
       
    74 	{
       
    75 	TStaFunction f = static_cast<TStaFunction>(aFunction);
       
    76 				
       
    77 	switch(f)
       
    78 		{
       
    79 		case EGetAttribute:
       
    80 			GetAttributeL(aMessage);
       
    81 			break;
       
    82 		case EGetStringAttributeSize:
       
    83 			GetStringAttributeSizeL(aMessage);
       
    84 			break;
       
    85 		case EGetStringAttributeData:
       
    86 			GetStringAttributeDataL(aMessage);
       
    87 			break;
       
    88 		case EGetPostDeliveryRights:
       
    89 			GetPostDeliveryRightsL(aMessage);
       
    90 			//RMessage2 object is closed by both TransferToClient() and SCS framework.
       
    91 			//return EFalse to prevent SCS to close the message object.
       
    92 			return EFalse;
       
    93 		case ESendKeyStream:
       
    94 			GetKeyStreamL(aMessage);
       
    95 			break;
       
    96 		case ESetKeyStreamSink:
       
    97 			SetKeyStreamSinkL(aMessage);
       
    98 			break;
       
    99 		case ESetSdpKeyStream:
       
   100 			SetSdpMediaFieldL(aMessage);
       
   101 			break;
       
   102 		case ESetSdpDocument:
       
   103 			SetSdpDocumentL(aMessage);
       
   104 			break;
       
   105 		case ESetIpSecAssoc:
       
   106 			SetIpSecAssociationL(aMessage);
       
   107 			break;
       
   108 		default:
       
   109 			User::Leave(KErrNotSupported);
       
   110 		}
       
   111 	return ETrue;
       
   112 	}//End of function DoServiceL
       
   113 
       
   114 
       
   115 void CStaSession::GetAttributeL(const RMessage2& aMessage)
       
   116 /**
       
   117  	Returns the value of an attribute requested by the client.
       
   118  	@param	aMessage	Standard server-side handle to message.
       
   119   */
       
   120 	{
       
   121 	TAttribute attr;
       
   122 	TPckg<TAttribute> attrBuf(attr);
       
   123 	aMessage.ReadL(0,attrBuf);
       
   124 	
       
   125 	VerifyRoL();
       
   126 	
       
   127 	TBool retVal = EFalse;
       
   128 	
       
   129 	switch(attr)
       
   130 		{
       
   131 		case EIsProgramProtected:
       
   132 			retVal = iRo->AccessRights() & EProgramProtected;
       
   133 			break;
       
   134 		case EIsServiceProtected:
       
   135 			retVal = iRo->AccessRights() & EServiceProtected;
       
   136 			break;
       
   137 		case ECanExport:
       
   138 			retVal = iRo->AccessRights() & ECanExportContent;
       
   139 			break;
       
   140 		case EMustProtectIfRecording:
       
   141 			retVal = iRo->AccessRights() & EMustProtectContentIfRecording;
       
   142 			break;
       
   143 		case ECanPlay:
       
   144 			retVal = iRo->AccessRights() & ECanPlayContent;
       
   145 			break;
       
   146 		default:
       
   147 			PanicClient(aMessage, KErrCAOutOfRange);
       
   148 		}
       
   149 	
       
   150 	// If the the return value is greater than 0, set the boolean value to ETrue
       
   151 	if(retVal)
       
   152 		{
       
   153 		retVal = ETrue;
       
   154 		}
       
   155 	
       
   156 	TPckg<TBool> retValBuf(retVal);
       
   157 	aMessage.WriteL(1, retValBuf);
       
   158 	}
       
   159 
       
   160 
       
   161 void CStaSession::GetStringAttributeSizeL(const RMessage2& aMessage)
       
   162 /**
       
   163  	Returns the size of the string attribute requested by the client.
       
   164  	@param	aMessage	Standard server-side handle to message.
       
   165   */
       
   166 	{
       
   167 	TStringAttribute strAttr;
       
   168 	TPckg<TStringAttribute> strAttrBuf(strAttr);
       
   169 	aMessage.ReadL(0,strAttrBuf);
       
   170 	
       
   171 	VerifyRoL();
       
   172 	TInt size = 0;
       
   173 	
       
   174 	switch(strAttr)
       
   175 		{
       
   176 		case EContentID:
       
   177 			size = iRo->ContentId()->Des().Size();
       
   178 			break;
       
   179 		case ERightsIssuerURI:
       
   180 			size = iRo->RightsIssuer()->Des().Size();
       
   181 			break;
       
   182 		default:
       
   183 			PanicClient(aMessage, KErrCAOutOfRange);
       
   184 		}
       
   185 	
       
   186 	TPckg<TInt> sizeBuf(size);
       
   187 	aMessage.WriteL(1, sizeBuf);
       
   188 	}
       
   189 
       
   190 
       
   191 void CStaSession::GetStringAttributeDataL(const RMessage2& aMessage)
       
   192 /**
       
   193  	Returns the value of a string attribute requested by the client.
       
   194  	@param	aMessage	Standard server-side handle to message.
       
   195   */
       
   196 	{
       
   197 	TStringAttribute strAttr;
       
   198 	TPckg<TStringAttribute> strAttrBuf(strAttr);
       
   199 	aMessage.ReadL(0,strAttrBuf);
       
   200 	
       
   201 	VerifyRoL();
       
   202 	HBufC8* str = NULL;
       
   203 	
       
   204 	switch(strAttr)
       
   205 	{
       
   206 	case EContentID:
       
   207 		str = iRo->ContentId();
       
   208 		break;
       
   209 	case ERightsIssuerURI:
       
   210 		str = iRo->RightsIssuer();
       
   211 		break;
       
   212 	default:
       
   213 		PanicClient(aMessage, KErrCAOutOfRange);
       
   214 	}
       
   215 	TPtr8 ptr(str->Des());
       
   216 	aMessage.WriteL(1, ptr);
       
   217 	}
       
   218 
       
   219 
       
   220 void CStaSession::GetPostDeliveryRightsL(const RMessage2& aMessage)
       
   221 /**
       
   222  	Returns the file handle of the requested post-acqusition rights, its content id, 
       
   223  	the post-acquisition rights' mime type and the post-acquisition content's mime type.
       
   224  	@param	aMessage	Standard server-side handle to message.
       
   225  */ 
       
   226 	{
       
   227 	VerifyRoL();
       
   228 	
       
   229 	//In this test agent, a pre-defined post-acquisition rights object is used.
       
   230 	//In real-life standards, the post-acquisition rights object would be generated
       
   231 	//from the rights object which is used to decode key stream.
       
   232 	
       
   233 	//Get the file path of the pre-defined post acqusition rights object
       
   234 	TFileName fPath(KStaPrivateFolder);
       
   235 	fPath[0] = Server()->iFs.GetSystemDriveChar();
       
   236 	//Convert 8-bit to 16-bit
       
   237 	HBufC* fName = HBufC::NewLC(iRo->ContentId()->Des().Length());
       
   238 	TPtr ptrName(fName->Des());
       
   239 	ptrName.Copy(iRo->ContentId()->Des());
       
   240 	fPath.Append(*fName);
       
   241 	fPath.Append(KRoFileExtension);
       
   242 	CleanupStack::PopAndDestroy(fName);
       
   243 	
       
   244 	//Open the post-acqusition rights object file
       
   245 	RFile f;
       
   246 	User::LeaveIfError(f.Open(Server()->iFs, fPath, EFileRead | EFileShareAny));
       
   247 	CleanupClosePushL(f);
       
   248 	
       
   249 	//Send the content id of the post-acquisition rights object
       
   250 	aMessage.WriteL(1, KPostAcquisitionCid());
       
   251 	//Send the mime type of the post-acquisition rights object
       
   252 	aMessage.WriteL(2, KPostAcquisitionRoMimeType());
       
   253 	//Send the mime type of the post-acquisition content
       
   254 	aMessage.WriteL(3, KPostAcquisitionContentMimeType());
       
   255 	
       
   256 	//Pass the file	handle to the client
       
   257 	User::LeaveIfError(f.TransferToClient(aMessage, 0));
       
   258 	//The message should have been completed
       
   259 	ASSERT(aMessage.IsNull());
       
   260 	CleanupStack::PopAndDestroy(&f);
       
   261 	}
       
   262 
       
   263 
       
   264 void CStaSession::GetKeyStreamL(const RMessage2& aMessage)
       
   265 /**
       
   266  	Gets an encrypyed short-term key from the client.
       
   267  	@param	aMessage	Standard server-side handle to message.
       
   268   */
       
   269 	{
       
   270 	TInt len = aMessage.GetDesMaxLengthL(0);
       
   271 	HBufC8* shortTermKey = HBufC8::NewLC(len);
       
   272 	TPtr8 ptr(shortTermKey->Des());
       
   273 	aMessage.ReadL(0,ptr);
       
   274 	
       
   275 	//Check if the long-term key key exists in the short-term key
       
   276 	TInt ret = shortTermKey->Find(*iRo->Key());
       
   277 	if(ret == KErrNotFound)
       
   278 		{
       
   279 		User::Leave(KErrGeneral);
       
   280 		}
       
   281 	
       
   282 	//Get the plain string (key)
       
   283 	HBufC8* decryptedKey = HBufC8::NewLC(ret);
       
   284 	TPtr8 ptrKey(decryptedKey->Des());
       
   285 	ptrKey.Copy(shortTermKey->Des().Ptr(), ret);
       
   286 	
       
   287 	CTestKeyAssociation* decryptedAssoc = CTestKeyAssociation::NewL(ptrKey);
       
   288 	CleanupStack::PushL(decryptedAssoc);
       
   289 	
       
   290 	iKeyStreamSink->ProcessNewKeyAssociationL(*decryptedAssoc);
       
   291 	
       
   292 	CleanupStack::PopAndDestroy(3, shortTermKey);
       
   293 	}
       
   294 
       
   295 
       
   296 void CStaSession::SetKeyStreamSinkL(const RMessage2& aMessage)
       
   297 /**
       
   298  	Gets a key stream sink from the client.
       
   299  	@param	aMessage	Standard server-side handle to message.
       
   300   */
       
   301 	{
       
   302 	TInt len = aMessage.GetDesMaxLengthL(0);
       
   303 	HBufC8* des = HBufC8::NewLC(len);
       
   304 	TPtr8 ptr(des->Des());
       
   305 	aMessage.ReadL(0,ptr);		
       
   306 	delete iKeyStreamSink;
       
   307 	iKeyStreamSink = NULL;
       
   308 	TRAPD(err, 
       
   309 		iKeyStreamSink = CKeyStreamSink::InternalizeLC(ptr); 
       
   310 		CleanupStack::Pop(iKeyStreamSink););
       
   311 	// In addition to the production supported key stream sinks, there is also the Test key stream sink
       
   312 	// If the production code could not load the key stream sink, it must be the test key stream sink - load it
       
   313 	if (err == KErrNotSupported)		
       
   314 		{		
       
   315 		RDesReadStream readStream(ptr);
       
   316 		CleanupClosePushL(readStream);		
       
   317 		iKeyStreamSink = CTestKeyStreamSink::NewL(readStream);
       
   318 		CleanupStack::PopAndDestroy(&readStream);
       
   319 		}		
       
   320 	else
       
   321 		User::LeaveIfError(err);	
       
   322 	CleanupStack::PopAndDestroy(des);
       
   323 	}
       
   324 
       
   325 void CStaSession::SetIpSecAssociationL(const RMessage2& aMessage)
       
   326 	{
       
   327 	TInt len = aMessage.GetDesMaxLengthL(0);
       
   328 	HBufC8* des = HBufC8::NewLC(len);
       
   329 	TPtr8 ptr(des->Des());
       
   330 	aMessage.ReadL(0,ptr);
       
   331 	
       
   332 	RDesReadStream readStream(ptr);
       
   333 	CleanupClosePushL(readStream);
       
   334 	
       
   335 	TInt32 spi = readStream.ReadInt32L();
       
   336 	HBufC8* encryptionKey = HBufC8::NewLC(readStream, 128);
       
   337 	HBufC8* authenticationKey = HBufC8::NewLC(readStream, 128);
       
   338 	
       
   339 	CKeyAssociation *ipSecKeyAssociation = CIpSecKeyAssociation::NewLC(spi, encryptionKey, authenticationKey);			
       
   340 	iKeyStreamSink->ProcessNewKeyAssociationL(*ipSecKeyAssociation);
       
   341 	CleanupStack::PopAndDestroy(5, des);
       
   342 	}
       
   343 
       
   344 void CStaSession::SetSdpMediaFieldL(const RMessage2& aMessage)
       
   345 /**
       
   346  	Gets an SDP object from the client.
       
   347  	@param	aMessage	Standard server-side handle to message.
       
   348   */
       
   349 	{
       
   350 #ifdef INTERNALLY_ENABLE_UPWARD_DEPENDENCY
       
   351 	TInt len = aMessage.GetDesMaxLengthL(0);
       
   352 	HBufC8* des = HBufC8::NewLC(len);
       
   353 	TPtr8 ptr(des->Des());
       
   354 	aMessage.ReadL(0,ptr);
       
   355 	
       
   356 	//Delete previous SDP and rights objects
       
   357 	delete iSdp;
       
   358 	iSdp = NULL;
       
   359 	delete iRo;
       
   360 	iRo = NULL;
       
   361 	
       
   362 	DoSetSdpMediaFieldL(Server()->iFs, iSdp, iRo, ptr, KStaPrivateFolder());
       
   363 	CleanupStack::PopAndDestroy(des);
       
   364 	
       
   365 	//Leave if no RO has been found
       
   366 	if(!iRo)
       
   367 		{
       
   368 		User::Leave(KErrCANoRights);
       
   369 		}
       
   370 #else
       
   371 	(void) aMessage;
       
   372 	User::Leave(KErrCANoRights);
       
   373 #endif
       
   374 	}
       
   375 
       
   376 void CStaSession::SetSdpDocumentL(const RMessage2& aMessage)
       
   377 /**
       
   378  	Sets the SDP document object coming from the client.
       
   379  	
       
   380  	@param	aMessage	Standard server-side handle to message.
       
   381   */
       
   382 	{
       
   383 #ifdef INTERNALLY_ENABLE_UPWARD_DEPENDENCY
       
   384 	TInt len = aMessage.GetDesMaxLengthL(0);
       
   385 	HBufC8* des = HBufC8::NewLC(len);
       
   386 	TPtr8 ptr(des->Des());
       
   387 	aMessage.ReadL(0,ptr);
       
   388 	
       
   389 	//Delete previous SDPDoc
       
   390 	delete iSdpDoc;
       
   391 	iSdpDoc = NULL;
       
   392 	
       
   393 	// Decode the SDP document object from the encoded data
       
   394 	iSdpDoc = CSdpDocument::DecodeL(*des);
       
   395 	CleanupStack::PopAndDestroy(des);
       
   396 #else
       
   397 	(void) aMessage;
       
   398 #endif
       
   399 	}
       
   400 
       
   401 void CStaSession::VerifyRoL()
       
   402 /**
       
   403  	Verifies that the rights object exists.
       
   404  */
       
   405 	{
       
   406 	if(!iRo)
       
   407 		{//The RO defined in the SDP does not exist
       
   408 		User::Leave(KErrCANoRights);
       
   409 		}
       
   410 	if(iRo->IsExpired())
       
   411 		{
       
   412 		User::Leave(KErrCANoPermission);
       
   413 		}
       
   414 	}
       
   415 
       
   416 void CStaSession::PanicClient(const RMessagePtr2& aMessage, TInt aReason)
       
   417 /**
       
   418 	Panic the client which sent the supplied message with
       
   419 	category KScsClientPanicCat and the supplied reason.
       
   420 
       
   421 	@param	aMessage		Client message.
       
   422 	@param	aReason			Why the client will be panicked.
       
   423 	@see KStaClientPanicCat
       
   424  */
       
   425 	{
       
   426 	aMessage.Panic(KStaClientPanicCat, aReason);
       
   427 	}