datacommsserver/esockserver/csock/cs_subconn.cpp
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2003-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 cs_subconn.cpp
       
    18 */
       
    19 
       
    20 #include <comms-infras/nifprvar.h>
       
    21 #include <ecom/ecom.h>
       
    22 #include <es_sock.h>
       
    23 
       
    24 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    25 #include <es_sock_partner.h>
       
    26 #include <es_sock_internal.h>
       
    27 #endif
       
    28 
       
    29 
       
    30 #include <comms-infras/sockmes.h>
       
    31 #include <connpref.h>
       
    32 #include <comms-infras/ss_log.h>
       
    33 #include <comms-infras/es_parameterbundle.h>
       
    34 #include <comms-infras/es_parameterfamily.h>
       
    35 
       
    36 
       
    37 #ifdef _DEBUG
       
    38 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
       
    39 // (if it could happen through user error then you should give it an explicit, documented, category + code)
       
    40 _LIT(KSpecAssert_ESockCSockcssbcn, "ESockCSockcssbcn");
       
    41 #endif
       
    42 
       
    43 using Meta::STypeId;
       
    44 
       
    45 EXPORT_C CSubConParameterSet* CSubConParameterSet::NewL(const STypeId& aTypeId)
       
    46 /** Creates a new sub-connection parameter set using ECOM to load the DLL plugin
       
    47     that implements the set.
       
    48 
       
    49 @param aTypeId Id of the class (Composed of Uid of the implementation and an integer sub-type
       
    50 @return a generic pointer to a specific parameter set if successful, otherwise leaves with system error code.
       
    51 */
       
    52 	{
       
    53 	return static_cast<CSubConParameterSet*>(Meta::SMetaDataECom::NewInstanceL(aTypeId));
       
    54 	}
       
    55 
       
    56 CSubConParameterSet::~CSubConParameterSet()
       
    57 /** Empty (virtual) sub-connection parameter set destructor
       
    58 */
       
    59 	{
       
    60 	}
       
    61 
       
    62 CSubConParameterSet::CSubConParameterSet()
       
    63 /** Empty sub-connection parameter set constructor
       
    64 */
       
    65 	{
       
    66 	}
       
    67 
       
    68 EXPORT_C CSubConGenericParameterSet::~CSubConGenericParameterSet()
       
    69 /** Empty (virtual) sub-connection generic parameter set destructor
       
    70 */
       
    71 	{
       
    72 	LOG( ESockLog::Printf(_L8("CSubConGenericParameterSet::~CSubConGenericParameterSet() %08x"), this););
       
    73 	}
       
    74 
       
    75 EXPORT_C CSubConGenericParameterSet::CSubConGenericParameterSet()
       
    76 /** Empty sub-connection generic parameter set constructor
       
    77 */
       
    78 	{
       
    79 	LOG( ESockLog::Printf(_L8("CSubConGenericParameterSet::CSubConGenericParameterSet() %08x"), this););
       
    80 	}
       
    81 
       
    82 EXPORT_C CSubConExtensionParameterSet::~CSubConExtensionParameterSet()
       
    83 /** Empty (virtual) sub-connection extension parameter set destructor
       
    84 */
       
    85 	{
       
    86 	}
       
    87 	
       
    88 EXPORT_C CSubConExtensionParameterSet::CSubConExtensionParameterSet()
       
    89 /** Empty sub-connection extension parameter set constructor
       
    90 */
       
    91 	{
       
    92 	}
       
    93 
       
    94 EXPORT_C CSubConParameterFamily* CSubConParameterFamily::NewL(RSubConParameterBundle& aBundle, TUint32 aFamilyId)
       
    95 /** Creates a new sub-connection parameter set family. This class is used as a container for a number of parameter
       
    96     sets (generic and extension) that make up a family. It is a specific instantiatable class and therefore creates
       
    97 	an instance of CSubConParameterFamily without using ECOM. 
       
    98 
       
    99 Note:
       
   100 The aBundle parameter that is passed into this method will take ownership of the newly created 
       
   101 CSubConParameterFamily object.  When the bundle is destroyed, this family object will also be 
       
   102 destroyed  (along with any parameter sets that are owned by the family).
       
   103 
       
   104 @param aBundle Family container (bundle) that this family is to be added to
       
   105 @param aFamilyId identifier for the specific family type, currently only 4, QoS (KSubConQoSFamily),Authorisation (KSubConAuthorisationFamily),
       
   106 CallDescrParams (KSubConnCallDescrParamsFamily) and ContextDescrParams (KSubConnContextDescrParamsFamily), are defined.
       
   107 @return a pointer to a sub-connection parameter family if successful, otherwise leaves with system error code.
       
   108 */
       
   109 	{
       
   110 	CSubConParameterFamily* family = new (ELeave) CSubConParameterFamily(aFamilyId);
       
   111 	CleanupStack::PushL(family);
       
   112 	family->ConstructL(aBundle);
       
   113 	CleanupStack::Pop(family);
       
   114 	return family;
       
   115 	}
       
   116 
       
   117 EXPORT_C CSubConParameterFamily* CSubConParameterFamily::NewL(CSubConParameterBundle& aBundle, TUint32 aFamilyId)
       
   118 /** Creates a new sub-connection parameter set family. This class is used as a container for a number of parameter
       
   119     sets (generic and extension) that make up a family. It is a specific instantiatable class and therefore creates
       
   120 	an instance of CSubConParameterFamily without using ECOM. 
       
   121 
       
   122 Note:
       
   123 The aBundle parameter that is passed into this method will take ownership of the newly created 
       
   124 CSubConParameterFamily object.  When the bundle is destroyed, this family object will also be 
       
   125 destroyed  (along with any parameter sets that are owned by the family).
       
   126 
       
   127 @param aBundle Family container (bundle) that this family is to be added to.
       
   128 @param aFamilyId identifier for the specific family type, currently only 4, QoS (KSubConQoSFamily),Authorisation (KSubConAuthorisationFamily),
       
   129 CallDescrParams (KSubConnCallDescrParamsFamily) and ContextDescrParams (KSubConnContextDescrParamsFamily), are defined.
       
   130 @return a pointer to a sub-connection parameter family if successful, otherwise leaves with system error code.
       
   131 */
       
   132 	{
       
   133 	CSubConParameterFamily* family = new (ELeave) CSubConParameterFamily(aFamilyId);
       
   134 	CleanupStack::PushL(family);
       
   135 	family->ConstructL(aBundle);
       
   136 	CleanupStack::Pop(family);
       
   137 	return family;
       
   138 	}
       
   139 
       
   140 EXPORT_C TInt32 CSubConParameterFamily::ExtractFamilyAndCreateBufferL(TPtrC8& aBuffer, TPtrC8& aContainerBuffer)
       
   141 /** Used internally to extract the family id for the descriptor storing the serialised version of this object (and others).
       
   142     It also sets up a new buffer that is the section of the original buffer that represents this object only.
       
   143 
       
   144 @param aBuffer Source buffer containing mulitple serialised objects (family at the start)
       
   145 @param aContainerBuffer Set up by this method and represents only the serialised data of the family object.
       
   146 @return the family Id, otherwise leaves with system error code.
       
   147 */
       
   148 	{
       
   149 	const TInt KDataHdrLen = 2 * static_cast<TInt>(sizeof(TUint32));
       
   150 
       
   151 	// Guard to ensure length of data, pointed to by the descriptor, is not too small,
       
   152 	// I.e. we are pointing to something!
       
   153 	if (aBuffer.Length() < KDataHdrLen)
       
   154 		{
       
   155 		User::Leave(KErrArgument);
       
   156 		}
       
   157  
       
   158  	// Obtain the 'length' value of the data pointed to by the descriptor
       
   159  	// Has to be at least size of header!
       
   160     TInt32 dataLength;
       
   161     Mem::Copy(&dataLength, aBuffer.Ptr(),sizeof(TInt32));
       
   162     
       
   163     
       
   164 	// Guard to ensure 'length' value of data contains enough data to read.
       
   165 	// i.e. aBuffer.Length() could point to some data whose 'length' is zero.
       
   166 	//
       
   167 	// Guard to ensure length of data, pointed to by the descriptor and specified by that
       
   168 	// descriptor, is not smaller that the length stated in the data itself.
       
   169 	// i.e. could be an array of objects.
       
   170 	if ((dataLength < KDataHdrLen) || (aBuffer.Length() < dataLength))
       
   171 		{
       
   172 		User::Leave(KErrArgument);
       
   173 		}
       
   174 
       
   175  	// Obtain the 'familyId' value of the data pointed to by the descriptor
       
   176 	TInt32 familyId;
       
   177 	Mem::Copy(&familyId, aBuffer.Ptr() + sizeof(TInt32),sizeof(TInt32));
       
   178 	
       
   179 	// Set up the container buffer
       
   180 	// Point it past the 'length' & 'familyId' fields (header).
       
   181 	// The data pointed to may be an array of user defined datatypes, and each datatype
       
   182 	// may have arbitrary data following the header fields.
       
   183 	// Point aContainerBuffer to that arbitrary data.
       
   184 	aContainerBuffer.Set(aBuffer.Ptr() + KDataHdrLen, dataLength - KDataHdrLen);
       
   185 	
       
   186 	// Move source buffer ptr on to the next family, plus any following data
       
   187 	aBuffer.Set(aBuffer.Ptr() + dataLength, aBuffer.Length() - dataLength);
       
   188 
       
   189 	return familyId;
       
   190 	}
       
   191 
       
   192 EXPORT_C CSubConParameterFamily* CSubConParameterFamily::LoadL(RSubConParameterBundle& aBundle, TPtrC8& aBuffer)
       
   193 /** Creates a new sub-connection parameter set family from a buffer containing the serialised object.
       
   194 
       
   195 Note:
       
   196 The aBundle parameter that is passed into this method will take ownership of the newly created 
       
   197 CSubConParameterFamily object.  When the bundle is destroyed, this family object will also be 
       
   198 destroyed  (along with any parameter sets that are owned by the family).
       
   199 
       
   200 @param aBundle Family container (bundle) that this family is to be added to
       
   201 @param aBuffer Buffer containing the serialised object information
       
   202 @return a pointer to a sub-connection parameter family if successful, otherwise leaves with system error code.
       
   203 */
       
   204 	{
       
   205 	TInt32 familyId = 0;
       
   206 	TPtrC8 containerBuffer(aBuffer.Ptr(), aBuffer.Length());
       
   207 	familyId = ExtractFamilyAndCreateBufferL(aBuffer, containerBuffer);
       
   208 	CSubConParameterFamily* family = new (ELeave) CSubConParameterFamily(familyId);
       
   209 	CleanupStack::PushL(family);
       
   210 	family->ConstructL(aBundle);
       
   211 	User::LeaveIfError(family->Load(containerBuffer));
       
   212 	CleanupStack::Pop(family);
       
   213 	return family;
       
   214 	}
       
   215 
       
   216 EXPORT_C CSubConParameterFamily* CSubConParameterFamily::LoadL(CSubConParameterBundle& aBundle, TPtrC8& aBuffer)
       
   217 /** Creates a new sub-connection parameter set family from a buffer containing the serialised object.
       
   218 
       
   219 Note:
       
   220 The aBundle parameter that is passed into this method will take ownership of the newly created 
       
   221 CSubConParameterFamily object.  When the bundle is destroyed, this family object will also be 
       
   222 destroyed  (along with any parameter sets that are owned by the family).
       
   223 
       
   224 @param aBundle Family container (bundle) that this family is to be added to
       
   225 @param aBuffer Buffer containing the serialised object information
       
   226 @return a pointer to a sub-connection parameter family if successful, otherwise leaves with system error code.
       
   227 */
       
   228 	{
       
   229 	TInt32 familyId = 0;
       
   230 	TPtrC8 containerBuffer(aBuffer.Ptr(), aBuffer.Length());
       
   231 	familyId = ExtractFamilyAndCreateBufferL(aBuffer, containerBuffer);
       
   232 	CSubConParameterFamily* family = new (ELeave) CSubConParameterFamily(familyId);
       
   233 	CleanupStack::PushL(family);
       
   234 	family->ConstructL(aBundle);
       
   235 	User::LeaveIfError(family->Load(containerBuffer));
       
   236 	CleanupStack::Pop(family);
       
   237 	return family;
       
   238 	}
       
   239 
       
   240 EXPORT_C CSubConParameterFamily::~CSubConParameterFamily()
       
   241 /** Sub-connection parameter family destructor. It cleans up the arrays deleting all
       
   242     the paarmeter sets it ownes
       
   243 */
       
   244 	{
       
   245 	iGenericSets.ResetAndDestroy();
       
   246 	iExtensionSets[ERequested].ResetAndDestroy();
       
   247 	iExtensionSets[EAcceptable].ResetAndDestroy();
       
   248 	iExtensionSets[EGranted].ResetAndDestroy();
       
   249 	}
       
   250 
       
   251 EXPORT_C void CSubConParameterFamily::SetGenericSetL(CSubConGenericParameterSet& aGenericSet, TParameterSetType aType)
       
   252 /** Assigns the generic parameter set of a sub-connection parameter set family.
       
   253 
       
   254 Note:
       
   255 The CSubConParameterFamily object takes ownership of the parameter set that is passed into 
       
   256 this method.  When the family object is destroyed, any parameter sets owned by this object 
       
   257 will also be destroyed.
       
   258 
       
   259 @param aGenericSet Generic Parameter Set to be assigned to the family (family takes ownership)
       
   260 @param aType The type of the set (requested, acceptable or granted)
       
   261 @exception leaves with KAlreadyExists if a set is already assigned to the family.
       
   262 */
       
   263 	{
       
   264 	if (iGenericSets[aType] != NULL)
       
   265 		{
       
   266 		User::Leave(KErrAlreadyExists);
       
   267 		}
       
   268 	iGenericSets[aType] = &aGenericSet;
       
   269 	}
       
   270 
       
   271 
       
   272 /**
       
   273 Adds an extension parameter set to a sub-connection parameter set family.
       
   274 
       
   275 Note:
       
   276 The CSubConParameterFamily object takes ownership of the parameter set that is passed into 
       
   277 this method.  When the family object is destroyed, any parameter sets owned by this object 
       
   278 will also be destroyed.
       
   279 
       
   280 @param aExtensionSet Extension Parameter Set to be added to the family (family takes ownership)
       
   281 @param aType The type of the set (requested, acceptable or granted)
       
   282 @exception leaves with KErrNoMemory in out of memeory conditions.
       
   283 */
       
   284 EXPORT_C void CSubConParameterFamily::AddExtensionSetL(CSubConExtensionParameterSet& aExtensionSet, TParameterSetType aType)
       
   285 	{
       
   286 	iExtensionSets[aType].AppendL(&aExtensionSet);
       
   287 	}
       
   288 
       
   289 
       
   290 /**
       
   291 Searches a sub-connection parameter family for an extension parameter set.
       
   292 DO NOT USE this form of the method. It is broken. This is only capable of finding extension sets
       
   293 contained within IP Subconnection Provider, and these extension sets have been deprecated.
       
   294 
       
   295 @param aSetId Although a TUid, this is the extension class Id 
       
   296 @param aType The type of the set from TParameterSetType (ERequested, EAcceptable or EGranted)
       
   297 @return Pointer to the extension set if found, otherwise a NULL pointer.
       
   298 */
       
   299 EXPORT_C CSubConExtensionParameterSet* CSubConParameterFamily::FindExtensionSet(TUid aSetId, TParameterSetType aType)
       
   300 	{
       
   301 	// Old Ipscpr Factory IUD  = 0x10204309
       
   302 	STypeId type = STypeId::CreateSTypeId(0x10204309, aSetId.iUid);
       
   303 	
       
   304 	TUint length = iExtensionSets[aType].Count();
       
   305 	for (TUint i = 0; i < length; ++i)
       
   306 		{
       
   307 		if (iExtensionSets[aType][i]->GetTypeId() == type)
       
   308 			{
       
   309 			return static_cast<CSubConExtensionParameterSet*>(iExtensionSets[aType][i]);
       
   310 			}
       
   311 		}
       
   312 		
       
   313 	return NULL;
       
   314    }
       
   315    
       
   316    
       
   317 /**
       
   318 Searches a sub-connection parameter family for an extension parameter set.
       
   319 @param aSetId The STypeId of the extension set
       
   320 @param aType The type of the set from TParameterSetType (ERequested, EAcceptable or EGranted)
       
   321 @return Pointer to the extension set if found, otherwise a NULL pointer.
       
   322 */
       
   323 EXPORT_C CSubConExtensionParameterSet* CSubConParameterFamily::FindExtensionSet(STypeId aSetId, TParameterSetType aType)
       
   324 	{
       
   325 	TUint length = iExtensionSets[aType].Count();
       
   326 	for (TUint i = 0; i < length; ++i)
       
   327 		{
       
   328 		if (iExtensionSets[aType][i]->GetTypeId() == aSetId)
       
   329 			{
       
   330 			return static_cast<CSubConExtensionParameterSet*>(iExtensionSets[aType][i]);
       
   331 			}
       
   332 		}
       
   333 		
       
   334 /*
       
   335  * This is a workaround for the relocated QoS extension parameter set classes. If an
       
   336  * extension set class is requested from the new factory and it can't be found another
       
   337  * check needs to be made to see if the equivalent deprecated class is there.
       
   338  *  
       
   339  * Normally this couldn't be done, but in this case its Ok since the classes
       
   340  * we're searching on are actually identical. 
       
   341  *
       
   342  * This can be removed once the deprecated class CSubConQosIPLinkR99ParamSet and
       
   343  * its friends are removed from ipscpr.
       
   344  *
       
   345  * Hardcoded values are being used here since;
       
   346  *    i)  They shouldn't be changing
       
   347  *    ii) It avoids having to include two unnecessary header files
       
   348  *
       
   349  * New Umts Factory UID    = 0x1020D460
       
   350  * Old Ipscpr Factory IUD  = 0x10204309
       
   351  * 
       
   352 */
       
   353    if (aSetId.iUid == TUid::Uid(0x1020D460))
       
   354       {
       
   355       STypeId alternateTypeId = STypeId::CreateSTypeId(0x10204309, aSetId.iType);
       
   356    	for (TUint i = 0; i < length; ++i)
       
   357    		{
       
   358    		if (iExtensionSets[aType][i]->GetTypeId() == alternateTypeId)
       
   359    			{
       
   360    			return static_cast<CSubConExtensionParameterSet*>(iExtensionSets[aType][i]);
       
   361    			}
       
   362    		}
       
   363       }
       
   364 
       
   365 	return NULL;
       
   366 	}
       
   367 
       
   368 EXPORT_C CSubConGenericParameterSet* CSubConParameterFamily::GetGenericSet(TParameterSetType aType)
       
   369 /** Accessor for the sub-connection generic parameter set of a family.
       
   370 
       
   371 @param aType The type of the set (requested, acceptable or granted)
       
   372 @return Pointer to the generic set if set, otherwise a NULL pointer.
       
   373 */
       
   374 	{
       
   375 	return static_cast<CSubConGenericParameterSet*>(iGenericSets[aType]);
       
   376 	}
       
   377 
       
   378 EXPORT_C TUint CSubConParameterFamily::Length() const
       
   379 /** Calculates the length of buffer required to serialise this parameter set family.
       
   380 
       
   381 @return Length of buffer required.
       
   382 */
       
   383 	{
       
   384 	return sizeof(TInt32) + sizeof(TInt32) + iGenericSets.Length() + iExtensionSets[ERequested].Length() + iExtensionSets[EAcceptable].Length() + iExtensionSets[EGranted].Length();
       
   385 	}
       
   386 
       
   387 EXPORT_C TInt CSubConParameterFamily::Load(TPtrC8& aBuffer)
       
   388 /** Instructs this sub-connection family to set its members based on the serialiesd data
       
   389     in the buffer passed.
       
   390 
       
   391 @param aBuffer Buffer containing the serialised family object
       
   392 @return KErrNone if successful, otherwise system wide error
       
   393 */
       
   394 	{
       
   395 	TInt ret = iGenericSets.GetTypeId().Check(aBuffer);
       
   396 	if (ret == KErrNone)
       
   397 		{
       
   398 		ret = iGenericSets.Load(aBuffer);
       
   399 		}
       
   400 	
       
   401 	if (ret != KErrNone)
       
   402 		{
       
   403 		return ret;
       
   404 		}
       
   405 
       
   406 	if (aBuffer.Length() == 0)
       
   407 		{
       
   408 		iGenericSets.ResetAndDestroy();
       
   409 		return KErrArgument;
       
   410 		}
       
   411 	
       
   412 	ret = iExtensionSets[ERequested].GetTypeId().Check(aBuffer);
       
   413 	if (ret == KErrNone)
       
   414 		{
       
   415 		ret = iExtensionSets[ERequested].Load(aBuffer);
       
   416 		}
       
   417 	if (ret != KErrNone)
       
   418 		{
       
   419 		iGenericSets.ResetAndDestroy();
       
   420 		return ret;
       
   421 		}
       
   422 
       
   423 	if (aBuffer.Length() > 0)
       
   424 		{
       
   425 		ret = iExtensionSets[EAcceptable].GetTypeId().Check(aBuffer);
       
   426 		if (ret == KErrNone)
       
   427 			{
       
   428 			ret = iExtensionSets[EAcceptable].Load(aBuffer);
       
   429 			}
       
   430 		if (ret != KErrNone)
       
   431 			{
       
   432 			iGenericSets.ResetAndDestroy();
       
   433 			iExtensionSets[ERequested].ResetAndDestroy();
       
   434 			return ret;
       
   435 			}
       
   436 		}
       
   437 
       
   438 	if (aBuffer.Length() > 0)
       
   439 		{
       
   440 		ret = iExtensionSets[EGranted].GetTypeId().Check(aBuffer);
       
   441 		if (ret == KErrNone)
       
   442 			{
       
   443 			ret = iExtensionSets[EGranted].Load(aBuffer);
       
   444 			}
       
   445 		if (ret != KErrNone)
       
   446 			{
       
   447 			iGenericSets.ResetAndDestroy();
       
   448 			iExtensionSets[ERequested].ResetAndDestroy();
       
   449 			iExtensionSets[EAcceptable].ResetAndDestroy();
       
   450 			return ret;
       
   451 			}
       
   452 		}
       
   453 	return KErrNone;
       
   454 	}
       
   455 
       
   456 EXPORT_C TInt CSubConParameterFamily::Store(TDes8& aDes) const
       
   457 /** Instructs this sub-connection family to create a serialised version of itself
       
   458     and append it to the buffer that has been passed.
       
   459 
       
   460 @param aDes Buffer to append the serialised object to
       
   461 @return KErrNone if successful, otherwise system wide error (e.g. KErrOverflow if the descriptor is too small)
       
   462 If unsuccessful, there is no guarantee as to the buffer or data stored in it.
       
   463 */
       
   464 	{	
       
   465 	// Needs to be at least this size to store len and familyId ptrs
       
   466 	// aDes can only grow upto MaxLength.
       
   467 	if (aDes.MaxLength() < (2 * static_cast<TInt>(sizeof(TUint32))))
       
   468 		{
       
   469 		return KErrOverflow;
       
   470 		}
       
   471 	
       
   472 	TUint len = Length();
       
   473 
       
   474 	aDes.Append((TUint8*)&len, sizeof(TUint32));
       
   475 	aDes.Append((TUint8*)&iFamilyId, sizeof(TUint32));
       
   476 
       
   477 	TInt ret = iGenericSets.Store(aDes);
       
   478 	if (ret != KErrNone)
       
   479 		{
       
   480 		return ret;
       
   481 		}
       
   482 
       
   483 	ret = iExtensionSets[ERequested].Store(aDes);
       
   484 	if (ret != KErrNone)
       
   485 		{
       
   486 		return ret;
       
   487 		}
       
   488 
       
   489 	ret = iExtensionSets[EAcceptable].Store(aDes);
       
   490 	if (ret != KErrNone)
       
   491 		{
       
   492 		return ret;
       
   493 		}
       
   494 
       
   495 	return iExtensionSets[EGranted].Store(aDes);
       
   496 	}
       
   497 
       
   498 EXPORT_C void CSubConParameterFamily::ClearAllParameters(TParameterSetType aType)
       
   499 /** Clears (removes and deletes) all parameter sets with the type specified
       
   500 
       
   501 @param aType The type of the set to be deleted(requested, acceptable or granted)
       
   502 */
       
   503 	{
       
   504 	if (iGenericSets[aType] != NULL)
       
   505 		{
       
   506 		delete iGenericSets[aType];
       
   507 		iGenericSets[aType] = NULL;
       
   508 		}
       
   509 	iExtensionSets[aType].ResetAndDestroy();
       
   510 	}
       
   511 
       
   512 void CSubConParameterFamily::CopyToFamilyL(RParameterFamily& aDest) const 
       
   513 	{
       
   514 	__ASSERT_DEBUG((TInt)CSubConParameterFamily::ENumValues == (TInt)RParameterFamily::ENumValues, User::Panic(KSpecAssert_ESockCSockcssbcn, 1));
       
   515 
       
   516 	TInt type=0;
       
   517 	for ( ; type<ENumValues; ++type)
       
   518 		{
       
   519 		XParameterSetBase* srcSet =
       
   520 			 static_cast<XParameterSetBase*>(iGenericSets[type]);
       
   521 		if(srcSet)
       
   522 			{
       
   523 			XParameterSetBase* newSet =
       
   524 				static_cast<XParameterSetBase*>
       
   525 				(XParameterSetBase::NewInstanceL(srcSet->GetTypeId()));
       
   526 			newSet->Copy(*srcSet);
       
   527 			aDest.AddParameterSetL(newSet,RParameterFamily::TParameterSetType(type));
       
   528 			}
       
   529 		}
       
   530 
       
   531 	for (type=0; type<ENumValues; ++type)
       
   532 		{
       
   533 		const RMetaDataEComContainer& srcContainer = iExtensionSets[type];
       
   534 		for (TInt srcidx=0; srcidx<srcContainer.Count(); ++srcidx)
       
   535 			{
       
   536 			XParameterSetBase* srcSet = static_cast<XParameterSetBase*>(srcContainer[srcidx]);
       
   537 			if(srcSet)
       
   538 				{
       
   539 				XParameterSetBase* newSet =
       
   540 					static_cast<XParameterSetBase*>
       
   541 					(XParameterSetBase::NewInstanceL(srcSet->GetTypeId()));
       
   542 				newSet->Copy(*srcSet);
       
   543 				aDest.AddParameterSetL(newSet,RParameterFamily::TParameterSetType(type));
       
   544 				}
       
   545 			}
       
   546 		}
       
   547 	}
       
   548 
       
   549 void CSubConParameterFamily::CopyFromFamilyL(RParameterFamily& aSrc)
       
   550 	{
       
   551 		__ASSERT_DEBUG((TInt)CSubConParameterFamily::ENumValues == (TInt)RParameterFamily::ENumValues, User::Panic(KSpecAssert_ESockCSockcssbcn, 2));
       
   552 
       
   553 	// The excuse for quoting the following UIds is:
       
   554 	//  They are the only types defined before the switchover to generic 
       
   555 	//   RFamilyBundles so are the only ones which will be subject to the
       
   556 	//   differentiation between "Generic" slot and "Extension" list.
       
   557 	//
       
   558 
       
   559 	//STypeId gentype_1(CSubConIPAddressInfoParamSet::EUid,CSubConIPAddressInfoParamSet::EType); // CSubConIPAddressInfoParamSet
       
   560 	STypeId gentype_1 = STypeId::CreateSTypeId(0x102822D5,1); // CSubConIPAddressInfoParamSet
       
   561 
       
   562 	//STypeId gentype_2(KSubConnGenericParamsImplUid,KSubConnQosGenericParamsType); // CSubConQosGenericParamSet
       
   563 	STypeId gentype_2 = STypeId::CreateSTypeId(KSubConnGenericParamsImplUid,1); // CSubConQosGenericParamSet
       
   564 
       
   565 	//STypeId gentype_3(KSubConnGenericParamsImplUid,KSubConnAuthorisationGenericParamsType); // CSubConAuthorisationGenericParamSet
       
   566 	STypeId gentype_3 = STypeId::CreateSTypeId(KSubConnGenericParamsImplUid,2); // CSubConAuthorisationGenericParamSet
       
   567 
       
   568 	//STypeId gentype_4(KSubConnGenericParamsImplUid,KFlowRequestParametersType); // CFlowRequestParameters
       
   569 	STypeId gentype_4 = STypeId::CreateSTypeId(KSubConnGenericParamsImplUid,3); // CFlowRequestParameters
       
   570 
       
   571 	//STypeId gentype_5(KSubConnGenericParamsImplUid,KSubConnProtocolGenericParamsType); // CSubConnectionProtocolParameterSet
       
   572 	STypeId gentype_5 = STypeId::CreateSTypeId(KSubConnGenericParamsImplUid,4); // CSubConnectionProtocolParameterSet
       
   573 
       
   574 	//STypeId gentype_6(KSubConChannelParamsImplUid,KSubConChannelParamsType); // CSubConChannelParamSet
       
   575 	STypeId gentype_6 = STypeId::CreateSTypeId(0x20019D42,9); // CSubConChannelParamSet
       
   576 	
       
   577 	for(TInt type=0; type<ENumValues; ++type)
       
   578 		{
       
   579 		TInt nSets = aSrc.CountParameterSets(RParameterFamily::TParameterSetType(type));
       
   580 		for(TInt srcidx=0 ; srcidx<nSets ; ++srcidx )
       
   581 			{
       
   582 			XParameterSetBase* srcSet = aSrc.GetParameterSetAtIndex(srcidx,RParameterFamily::TParameterSetType(type));
       
   583 			
       
   584 			TBool isGenericSet = 
       
   585 				(srcSet->IsTypeOf(gentype_1) || 
       
   586 			     srcSet->IsTypeOf(gentype_2) || 
       
   587 			     srcSet->IsTypeOf(gentype_3) || 
       
   588 			     srcSet->IsTypeOf(gentype_4) || 
       
   589 			     srcSet->IsTypeOf(gentype_5) || 
       
   590 			     srcSet->IsTypeOf(gentype_6) ) ;
       
   591 
       
   592 			XParameterSetBase* newSet =
       
   593 				static_cast<XParameterSetBase*>
       
   594 				(XParameterSetBase::NewInstanceL(srcSet->GetTypeId()));
       
   595 			
       
   596 			newSet->Copy(*srcSet);
       
   597 			if(isGenericSet)
       
   598 				{
       
   599 				CSubConGenericParameterSet &genPs =
       
   600 					static_cast<CSubConGenericParameterSet&>(*newSet);
       
   601 				SetGenericSetL(genPs,TParameterSetType(type));
       
   602 				}
       
   603 			else
       
   604 				{
       
   605 				CSubConExtensionParameterSet &extPs =
       
   606 					static_cast<CSubConExtensionParameterSet&>(*newSet);
       
   607 				AddExtensionSetL(extPs,TParameterSetType(type));
       
   608 				}
       
   609 			}
       
   610 		}
       
   611 	}
       
   612 
       
   613 
       
   614 EXPORT_C CSubConParameterFamily::CSubConParameterFamily(TUint32 aFamilyId)
       
   615 	: iFamilyId(aFamilyId)
       
   616 /** Empty sub-connection parameter family constructor
       
   617 
       
   618 @param aFamilyId identifier for the specific family type, currently only 4, QoS (KSubConQoSFamily),Authorisation (KSubConAuthorisationFamily),
       
   619 CallDescrParams (KSubConnCallDescrParamsFamily) and ContextDescrParams (KSubConnContextDescrParamsFamily), are defined.
       
   620 */
       
   621 	{
       
   622 	}
       
   623 
       
   624 EXPORT_C void CSubConParameterFamily::ConstructL(RSubConParameterBundle& aBundle)
       
   625 /** Set up the sub-connection family with empty sets
       
   626 
       
   627 Note:
       
   628 The aBundle parameter that is passed into this method will take ownership of the newly created 
       
   629 CSubConParameterFamily object.  When the bundle is destroyed, this family object will also be 
       
   630 destroyed  (along with any parameter sets that are owned by the family).
       
   631 
       
   632 @param aBundle Bundle (container) the family is to be added to
       
   633 @exception leaves with KErrNoMemory in out of memory conditions
       
   634 */
       
   635 	{
       
   636 	iGenericSets.AppendL(NULL);
       
   637 	iGenericSets.AppendL(NULL);
       
   638 	iGenericSets.AppendL(NULL);
       
   639 	aBundle.AddFamilyL(this);
       
   640 	}
       
   641 
       
   642 EXPORT_C void CSubConParameterFamily::ConstructL(CSubConParameterBundle& aBundle)
       
   643 /** Set up the sub-connection family with empty sets
       
   644 
       
   645 Note:
       
   646 The aBundle parameter that is passed into this method will take ownership of the newly created 
       
   647 CSubConParameterFamily object.  When the bundle is destroyed, this family object will also be 
       
   648 destroyed  (along with any parameter sets that are owned by the family).
       
   649 
       
   650 @param aBundle Bundle (container) the family is to be added to
       
   651 @exception leaves with KErrNoMemory in out of memory conditions
       
   652 */
       
   653 	{
       
   654 	iGenericSets.AppendL(NULL);
       
   655 	iGenericSets.AppendL(NULL);
       
   656 	iGenericSets.AppendL(NULL);
       
   657 	aBundle.AddFamilyL(this);
       
   658 	}
       
   659 
       
   660 CSubConParameterBundle::CSubConParameterBundle(const CSubConParameterBundle& /*aBundle*/)
       
   661 /** Copy Constructor
       
   662 */
       
   663 	{
       
   664 	__ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockCSockcssbcn, 3));//can be Unreachable in future
       
   665 	}
       
   666 
       
   667 CSubConParameterBundle& CSubConParameterBundle::operator=(const CSubConParameterBundle& /*aBundle*/)
       
   668 /** Assignment operator
       
   669 */
       
   670 	{
       
   671 	__ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockCSockcssbcn, 4));//can be Unreachable in future
       
   672 	return *this;
       
   673 	}
       
   674 
       
   675 TInt RSubConParameterBundle::CheckBundle() const
       
   676 /** Check to see if the handle has a heap object. If it hasn't, it creates one
       
   677 
       
   678 @return KErrNone if successful, otherwise a system wide error
       
   679 */
       
   680 	{
       
   681 	if (!iBundle)
       
   682 		{
       
   683 		TRAPD(ret, iBundle = CSubConParameterBundle::NewL());
       
   684 		return ret;
       
   685 		}
       
   686 	return KErrNone;
       
   687 	}
       
   688 
       
   689 EXPORT_C RSubConParameterBundle::RSubConParameterBundle()
       
   690 	: iBundle(NULL)
       
   691 /** Empty sub-connection parameter bundle constructor
       
   692 */
       
   693 	{
       
   694 	}
       
   695 
       
   696 RSubConParameterBundle::RSubConParameterBundle(const RSubConParameterBundle& /*aBundle*/)
       
   697 /** Copy Constructor
       
   698 */
       
   699 	{
       
   700 	__ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockCSockcssbcn, 5));//can be Unreachable in future
       
   701 	}
       
   702 
       
   703 RSubConParameterBundle& RSubConParameterBundle::operator=(const RSubConParameterBundle& /*aBundle*/)
       
   704 /** Assignment operator
       
   705 */
       
   706 	{
       
   707 	__ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockCSockcssbcn, 6));//can be Unreachable in future
       
   708 	return *this;
       
   709 	}
       
   710 
       
   711 EXPORT_C void RSubConParameterBundle::Close()
       
   712 /** Close the parameter bundle handle
       
   713 */
       
   714 	{
       
   715 	if (iBundle)
       
   716 		{
       
   717 		iBundle->Close();
       
   718 		iBundle = NULL;
       
   719 		}
       
   720 	}
       
   721 
       
   722 EXPORT_C TUint RSubConParameterBundle::Length() const
       
   723 /** Calculates the length of buffer required to serialise this parameter set bundle.
       
   724 
       
   725 @return Length of buffer required.
       
   726 */
       
   727 	{
       
   728 	TInt err = CheckBundle();
       
   729 	return (err==KErrNone)? iBundle->Length() : 0;
       
   730 	}
       
   731 
       
   732 EXPORT_C TInt RSubConParameterBundle::Load(const TDesC8& aDes)
       
   733 /** Instructs this sub-connection bundle to set its members based on the serialiesd data
       
   734     in the buffer passed.
       
   735 
       
   736 @param aDes Buffer containing the serialised bundle object
       
   737 @return KErrNone if successful, otherwise system wide error
       
   738 */
       
   739 	{
       
   740 	TInt ret = CheckBundle();
       
   741 	if (ret == KErrNone)
       
   742 		ret = iBundle->Load(aDes);
       
   743 	return ret;
       
   744 	}
       
   745 
       
   746 EXPORT_C TInt RSubConParameterBundle::Store(TDes8& aDes) const
       
   747 /** Instructs this sub-connection parameter bundle to create a serilised version of itself
       
   748     and append it to the buffer that has been passed.
       
   749 
       
   750 @param aDes Buffer to append the serialised object to
       
   751 @return KErrNone if successful, otherwise system wide error (e.g. EKrrOverflow if the descriptor is too small)
       
   752 If unsuccessful, there is no guarantee as to the buffer or data stored in it.
       
   753 */
       
   754 	{
       
   755 	TInt ret = CheckBundle();
       
   756 	if (ret == KErrNone)
       
   757 		ret = iBundle->Store(aDes);
       
   758 	return ret;
       
   759 	}
       
   760 
       
   761 EXPORT_C void RSubConParameterBundle::AddFamilyL(CSubConParameterFamily* aFamily)
       
   762 /** Add a sub-connection parameter family to the bundle.
       
   763 
       
   764 Note:
       
   765 The RSubConParameterBundle object takes ownership of the parameter family that is passed 
       
   766 into this method.  When the bundle object is destroyed, any family owned by this object 
       
   767 will also be destroyed.
       
   768 
       
   769 @param aFamily Family to be added (bundle takes ownership)
       
   770 @exception leaves with KErrNoMemory in out of memory conditions
       
   771 */
       
   772 	{
       
   773 	User::LeaveIfError(CheckBundle());
       
   774 	iBundle->AddFamilyL(aFamily);
       
   775 	}
       
   776 
       
   777 EXPORT_C CSubConParameterFamily* RSubConParameterBundle::FindFamily(TUint32 aFamilyId)
       
   778 /** Search the sub-connection parameter bundle for a parameter family
       
   779 
       
   780 @param aFamilyId Id of the family to match against. It is an identifier for the specific family type, currently only 4, QoS (KSubConQoSFamily),Authorisation (KSubConAuthorisationFamily),
       
   781 CallDescrParams (KSubConnCallDescrParamsFamily) and ContextDescrParams (KSubConnContextDescrParamsFamily), are defined.
       
   782 @return Matching family or NULL pointer if not found
       
   783 */
       
   784 	{
       
   785 	if (CheckBundle() != KErrNone)
       
   786 		return NULL;
       
   787 	else
       
   788 		return iBundle->FindFamily(aFamilyId);
       
   789 	}
       
   790 
       
   791 EXPORT_C void RSubConParameterBundle::ClearAllParameters(CSubConParameterFamily::TParameterSetType aType)
       
   792 /** Clears (removes and deletes) all parameter sets with the type specified (delegated to the families)
       
   793 
       
   794 @param aType The type of the set to be deleted(requested, acceptable or granted)
       
   795 */
       
   796 	{
       
   797 	if (iBundle != NULL)
       
   798 		{
       
   799 		iBundle->ClearAllParameters(aType);
       
   800 		}
       
   801 	}
       
   802 
       
   803 
       
   804 EXPORT_C void RSubConParameterBundle::CopyToFamilyBundleL(RParameterFamilyBundle& aDest) const
       
   805 	{
       
   806 	aDest.CreateL();
       
   807 	User::LeaveIfError(CheckBundle());
       
   808 	
       
   809 	TUint length = iBundle->iFamilies.Count();
       
   810 	for (TUint i = 0; i < length; ++i)
       
   811 		{
       
   812 		CSubConParameterFamily* srcScpf = iBundle->iFamilies[i];
       
   813 		RParameterFamily newPf;
       
   814 		newPf.CreateL(aDest,srcScpf->Id());
       
   815 		srcScpf->CopyToFamilyL(newPf);
       
   816 		}
       
   817 	}
       
   818 	
       
   819 EXPORT_C void RSubConParameterBundle::CopyFromFamilyBundleL(RParameterFamilyBundle& aSrc)
       
   820 	{
       
   821 	if (aSrc.IsNull())
       
   822 		{
       
   823 		User::Leave(KErrNotReady);
       
   824 		}
       
   825 	
       
   826 	RParameterFamily srcPf;
       
   827 	TInt index=0;
       
   828 	while( ! (srcPf=aSrc.GetFamilyAtIndex(index++)).IsNull() )
       
   829 		{
       
   830 		CSubConParameterFamily* newScpf = CSubConParameterFamily::NewL(*this,srcPf.Id());
       
   831 		newScpf->CopyFromFamilyL(srcPf);
       
   832 		}
       
   833 	}
       
   834 
       
   835 EXPORT_C CSubConParameterBundle* CSubConParameterBundle::NewL()
       
   836 /** Creates a new instance of a sub-connection parameter bundle (heap object)
       
   837     Can be used directly as a CObject or via the RSubConParameterBundle handle.
       
   838 
       
   839 @return newly created instance of a sub-connection parameter bundle
       
   840 @exception leaves with KErrNoMemory in out of memory conditions
       
   841 */
       
   842 	{
       
   843 	return new (ELeave) CSubConParameterBundle();
       
   844 	}
       
   845 
       
   846 EXPORT_C CSubConParameterBundle* CSubConParameterBundle::LoadL(TDesC8& aDes)
       
   847 /** Creates a new sub-connection parameter set bunlde from a buffer containing the serialised object.
       
   848 
       
   849 @param aDes Buffer containing the serialised object information
       
   850 @return a pointer to a sub-connection parameter bundle if successful, otherwise leaves with system error code.
       
   851 */
       
   852 	{
       
   853 	CSubConParameterBundle* obj = new (ELeave) CSubConParameterBundle();
       
   854 	CleanupStack::PushL(obj);
       
   855 	User::LeaveIfError(obj->Load(aDes));
       
   856 	CleanupStack::Pop(obj);
       
   857 	return obj;
       
   858 	}
       
   859 
       
   860 EXPORT_C CSubConParameterBundle::~CSubConParameterBundle()
       
   861 /** Sub-connection parameter bundle destructor, clear up the families
       
   862 */
       
   863 	{
       
   864 	iFamilies.ResetAndDestroy();
       
   865 	}
       
   866 
       
   867 EXPORT_C TUint CSubConParameterBundle::Length() const
       
   868 /** Calculates the length of buffer required to serialise this parameter set bundle.
       
   869 
       
   870 @return Length of buffer required.
       
   871 */
       
   872 	{
       
   873 	TInt length = 0;
       
   874 	TUint count = iFamilies.Count();
       
   875 	for (TUint i = 0; i < count; ++i)
       
   876 		{
       
   877 		length += iFamilies[i]->Length();
       
   878 		}
       
   879 	return length;
       
   880 	}
       
   881 
       
   882 EXPORT_C TInt CSubConParameterBundle::Load(const TDesC8& aDes)
       
   883 /** Instructs this sub-connection bundle to set its members based on the serialiesd data
       
   884     in the buffer passed.
       
   885 
       
   886 @param aDes Buffer containing the serialised bundle object
       
   887 @return KErrNone if successful, otherwise system wide error
       
   888 */
       
   889 	{
       
   890 	TPtrC8 buf(aDes);
       
   891 
       
   892 	while (buf.Length() > 0)
       
   893 		{
       
   894 		TRAPD(ret, CSubConParameterFamily::LoadL(*this, buf));
       
   895 		if (ret != KErrNone)
       
   896 			{
       
   897 			iFamilies.ResetAndDestroy();
       
   898 			return ret;
       
   899 			}
       
   900 		}
       
   901 	return KErrNone;
       
   902 	}
       
   903 
       
   904 EXPORT_C TInt CSubConParameterBundle::Store(TDes8& aDes) const
       
   905 /** Instructs this sub-connection parameter bundle to create a serilised version of itself
       
   906     and append it to the buffer that has been passed.
       
   907 
       
   908 @param aDes Buffer to append the serialised object to
       
   909 @return KErrNone if successful, otherwise system wide error (e.g. EKrrOverflow if the descriptor is too small)
       
   910 If unsuccessful, there is no guarantee as to the buffer or data stored in it.
       
   911 */
       
   912 	{
       
   913 	TUint length = iFamilies.Count();
       
   914 
       
   915 	for (TUint i = 0; i < length; ++i)
       
   916 		{
       
   917 		TInt ret = iFamilies[i]->Store(aDes);
       
   918 		if (ret != KErrNone)
       
   919 			{
       
   920 			aDes.Zero();
       
   921 			return ret;
       
   922 			}
       
   923 		}
       
   924 	return KErrNone;
       
   925 	}
       
   926 
       
   927 EXPORT_C void CSubConParameterBundle::AddFamilyL(CSubConParameterFamily* aFamily)
       
   928 /** Add a sub-connection parameter family to the bundle.
       
   929 
       
   930 Note:
       
   931 The CSubConParameterBundle object takes ownership of the parameter family that is passed 
       
   932 into this method.  When the bundle object is destroyed, any family owned by this object 
       
   933 will also be destroyed.
       
   934 
       
   935 @param aFamily Family to be added (bundle takes ownership)
       
   936 @exception leaves with KErrNoMemory in out of memory conditions
       
   937 */
       
   938 	{
       
   939 	iFamilies.AppendL(aFamily);
       
   940 	}
       
   941 
       
   942 EXPORT_C CSubConParameterFamily* CSubConParameterBundle::FindFamily(TUint32 aFamilyId)
       
   943 /** Search the sub-connection parameter bundle for a parameter family
       
   944 
       
   945 @param aFamilyId Id of the family to match against. It is an identifier for the specific family type, currently only 4, QoS (KSubConQoSFamily),Authorisation (KSubConAuthorisationFamily),
       
   946 CallDescrParams (KSubConnCallDescrParamsFamily) and ContextDescrParams (KSubConnContextDescrParamsFamily), are defined.
       
   947 @return Matching family or NULL pointer if not found
       
   948 */
       
   949 	{
       
   950 	TUint length = iFamilies.Count();
       
   951 	for (TUint i = 0; i < length; ++i)
       
   952 		{
       
   953 		if (iFamilies[i]->Id() == aFamilyId)
       
   954 			{
       
   955 			return iFamilies[i];
       
   956 			}
       
   957 		}
       
   958 	return NULL;
       
   959 	}
       
   960 
       
   961 EXPORT_C CSubConParameterFamily* CSubConParameterBundle::FindFamily(TUint32 aFamilyId) const
       
   962 /** Search the sub-connection parameter bundle for a parameter family
       
   963 
       
   964 @param aFamilyId Id of the family to match against. It is an identifier for the specific family type, currently only 4, QoS (KSubConQoSFamily),Authorisation (KSubConAuthorisationFamily),
       
   965 CallDescrParams (KSubConnCallDescrParamsFamily) and ContextDescrParams (KSubConnContextDescrParamsFamily), are defined.
       
   966 @return Matching family or NULL pointer if not found
       
   967 */
       
   968 	{
       
   969 	TUint length = iFamilies.Count();
       
   970 	for (TUint i = 0; i < length; ++i)
       
   971 		{
       
   972 		if (iFamilies[i]->Id() == aFamilyId)
       
   973 			{
       
   974 			return iFamilies[i];
       
   975 			}
       
   976 		}
       
   977 	return NULL;
       
   978 	}
       
   979 
       
   980 EXPORT_C void CSubConParameterBundle::ClearAllParameters(CSubConParameterFamily::TParameterSetType aType)
       
   981 /** Clears (removes and deletes) all parameter sets with the type specified (delegated to the families)
       
   982 
       
   983 @param aType The type of the set to be deleted(requested, acceptable or granted)
       
   984 */
       
   985 	{
       
   986 	TUint length = iFamilies.Count();
       
   987 	for (TUint i = 0; i < length; ++i)
       
   988 		{
       
   989 		iFamilies[i]->ClearAllParameters(aType);
       
   990 		}
       
   991 	}
       
   992 
       
   993 EXPORT_C CSubConParameterBundle::CSubConParameterBundle()
       
   994 /** Empty sub-connection generic parameter bundle constructor
       
   995 */
       
   996 	{
       
   997 	}
       
   998 
       
   999 EXPORT_C TNotificationEventBuf::TNotificationEventBuf()
       
  1000 	{
       
  1001 	SetLength(this->MaxLength());
       
  1002 	FillZ();
       
  1003 	}
       
  1004 
       
  1005 EXPORT_C TNotificationEventBuf::~TNotificationEventBuf()
       
  1006 	{
       
  1007 	}
       
  1008 	
       
  1009 EXPORT_C TBool TNotificationEventBuf::IsGeneric() const
       
  1010 /** Check whether an event is a generic event (not an extension)
       
  1011 
       
  1012 @return ETrue if the event is generic, otherwise EFalse
       
  1013 */
       
  1014 	{
       
  1015 	return GroupId() == KSubConnGenericEventsImplUid;
       
  1016 	}
       
  1017 
       
  1018 EXPORT_C TInt32 TNotificationEventBuf::GroupId() const
       
  1019 /** Provides the group id (Uid) of the event
       
  1020 
       
  1021 @return Group id in the form of a UId (Could be generic or any extension uid)
       
  1022 */
       
  1023 	{
       
  1024 	return *((TInt32*)Ptr());
       
  1025 	}
       
  1026 
       
  1027 EXPORT_C TUint32 TNotificationEventBuf::Id() const
       
  1028 /** Provides the sub-type Id of the event
       
  1029 
       
  1030 @return sub-type id
       
  1031 */
       
  1032 	{
       
  1033 	return *((TUint32*)(Ptr() + sizeof(TUint32)));
       
  1034 	}
       
  1035 
       
  1036 EXPORT_C CSubConNotificationEvent* CSubConNotificationEvent::NewL(const STypeId& aTypeId)
       
  1037 /** Creates a new sub-connection event using ECOM to load the DLL plugin
       
  1038     that implements the event.
       
  1039 
       
  1040 @param aTypeId Id of the class (Composed of Uid of the implementation and an integer sub-type)
       
  1041 @return a generic pointer to a specific event if successful, otherwise leaves with system error code.
       
  1042 */
       
  1043 	{
       
  1044 	return static_cast<CSubConNotificationEvent*>(Meta::SMetaDataECom::NewInstanceL(aTypeId));
       
  1045 	}
       
  1046 
       
  1047 EXPORT_C CSubConNotificationEvent* CSubConNotificationEvent::NewL(const TNotificationEventBuf& aEventBuffer)
       
  1048 /** Creates a new sub-connection event using ECOM to load the DLL plugin
       
  1049     that implements the event.
       
  1050 
       
  1051 @param aEventBuffer A Buffer containing the serialised form of the event object
       
  1052 @return a generic pointer to a specific event if successful, otherwise leaves with system error code.
       
  1053 */
       
  1054 	{
       
  1055 	TPtrC8 buf(aEventBuffer.Ptr(), aEventBuffer.Length());
       
  1056 	return static_cast<CSubConNotificationEvent*>(Meta::SMetaDataECom::LoadL(buf));
       
  1057 	}
       
  1058 
       
  1059 EXPORT_C TBool CSubConNotificationEvent::IsGeneric() const
       
  1060 /** Check whether an event is a generic event (not an extension)
       
  1061 
       
  1062 @return ETrue if the event is generic, otherwise EFalse
       
  1063 */
       
  1064 	{
       
  1065 	return GetTypeId().iUid.iUid == KSubConnGenericEventsImplUid;
       
  1066 	}
       
  1067 
       
  1068 EXPORT_C TInt32 CSubConNotificationEvent::GroupId() const
       
  1069 /** Provides the group id (Uid) of the event
       
  1070 
       
  1071 @return Group id in the form of a UId (Could be generic or any extension uid)
       
  1072 */
       
  1073 	{
       
  1074 	return static_cast<TInt32>(GetTypeId().iUid.iUid);
       
  1075 	}
       
  1076 
       
  1077 EXPORT_C TUint32 CSubConNotificationEvent::Id() const
       
  1078 /** Provides the sub-type Id of the event
       
  1079 
       
  1080 @return sub-type id
       
  1081 */
       
  1082 	{
       
  1083 	return GetTypeId().iType;
       
  1084 	}
       
  1085 
       
  1086 EXPORT_C RSubConnection::RSubConnection()
       
  1087 /** Empty sub-connection handle constructor
       
  1088 */
       
  1089 	{
       
  1090 	}
       
  1091 
       
  1092 EXPORT_C TInt RSubConnection::Open(RSocketServ& aServer, TSubConnType aSubConnType, RConnection& aConnection)
       
  1093 /** Opens a new RSubConnection instance.
       
  1094 
       
  1095 @param aSocketServer Socket Server session.
       
  1096 @param aSubConnType specifies the type of sub connection, the different available types are defined by TSubConnType.
       
  1097 @param aConnection Parent Connection that is to be sub divided by this sub-connection
       
  1098 @return KErrNone if successful, otherwise another of the system wide error codes.
       
  1099 */
       
  1100     {
       
  1101     return Open(aServer, static_cast<TSubConnOpen::TSubConnType>(aSubConnType), aConnection);
       
  1102     }
       
  1103 
       
  1104 EXPORT_C void RSubConnection::Close()
       
  1105 /** Closes the sub-connection.
       
  1106 
       
  1107 The sub-connection will not be dropped immediately: it will be dropped when there 
       
  1108 is no more data traffic on the sub-connection. 
       
  1109 */
       
  1110 	{
       
  1111 	LOG( ESockLog::Printf(_L8("RSubConnection %08x:\tClose() tid %d"), this, (TUint)RThread().Id()););
       
  1112 	CloseSubSession(ESCClose);
       
  1113 	REComSession::FinalClose();
       
  1114 	}
       
  1115 	
       
  1116 EXPORT_C void RSubConnection::Start(TRequestStatus& aStatus)
       
  1117 /**  
       
  1118 Unused
       
  1119 */
       
  1120     {
       
  1121 	LOG( ESockLog::Printf(_L8("RSubConnection %08x:\tStart() async tid %d"), this, (TUint)RThread().Id()););
       
  1122 	SendReceive(ESCStart, TIpcArgs(), aStatus);
       
  1123     }
       
  1124 
       
  1125 EXPORT_C TInt RSubConnection::Start()
       
  1126 /**
       
  1127 Unused
       
  1128 */
       
  1129     {
       
  1130 	LOG( ESockLog::Printf(_L8("RSubConnection %08x:\tStart() sync tid %d"), this, (TUint)RThread().Id()););
       
  1131 	TRequestStatus status;
       
  1132 	Start(status);
       
  1133 	User::WaitForRequest(status);
       
  1134 	return status.Int();
       
  1135     }
       
  1136 
       
  1137 EXPORT_C TInt RSubConnection::Stop()
       
  1138 /**
       
  1139 Unused
       
  1140 */
       
  1141     {
       
  1142 	LOG( ESockLog::Printf(_L8("RSubConnection %08x:\tStop() tid %d"), this, (TUint)RThread().Id()););
       
  1143 	return SendReceive(ESCStop, TIpcArgs());
       
  1144     }
       
  1145 
       
  1146 
       
  1147 EXPORT_C TInt RSubConnection::Open(RSocketServ& aServer, TSubConnOpen::TSubConnType aSubConnType, RConnection& aConnection)
       
  1148 /** Opens a new RSubConnection instance.
       
  1149 
       
  1150 @param aServer Socket Server session.
       
  1151 @param aSubConnType EAttachToDefault when attaching to default or ECreateNew for new one
       
  1152 @param aConnection Parent Connection that is to be sub divided by this sub-connection
       
  1153 @return KErrNone if successful, otherwise another of the system wide error codes.
       
  1154 */
       
  1155 	{
       
  1156 
       
  1157 	if(SubSessionHandle() == KNullHandle)
       
  1158 		{
       
  1159 		// passing an RConnection which doesn't belong to the same session is an error
       
  1160 		if (!aConnection.SameSession(aServer.Handle()))
       
  1161 			{
       
  1162 			return KErrArgument;
       
  1163 			}
       
  1164 
       
  1165 		TSubConnOpen arg;
       
  1166 		arg.iType   = aSubConnType;
       
  1167 		arg.iHandle = aConnection.SubSessionHandle();
       
  1168 		TPckgC<TSubConnOpen> buf(arg);
       
  1169 
       
  1170 
       
  1171 		const TInt ret = CreateSubSession(aServer, ESCCreate,TIpcArgs(&buf));		
       
  1172 		LOG( ESockLog::Printf(_L8("RSubConnection %08x:\tOpen() tid %d"), this, (TUint)RThread().Id()););
       
  1173 		return ret;
       
  1174 		}
       
  1175 	else
       
  1176 		{
       
  1177 		return KErrInUse;
       
  1178 		}
       
  1179 	}
       
  1180 
       
  1181 EXPORT_C void RSubConnection::Add(RSocket& aSocket, TRequestStatus& aStatus)
       
  1182 /** Associate a socket with a subconnection. The socket must already be using the same connection
       
  1183     or the association attempt will fail. The completion of this method does not indicate that the
       
  1184 	socket is now running over the sub-connection, it only indicates that the association is complete
       
  1185 	and a negotiation has started to move the socket onto the subconnection. An event (via eventNotification)
       
  1186 	will be sent once the socket is running on the sub-connection.
       
  1187 
       
  1188 @param aSocket Socket to be associated with the Sub-Connection
       
  1189 @param aStatus Status to complete when socket has been added (or failed to add)
       
  1190 @return KErrNone if successful, otherwise a system wide error
       
  1191 */
       
  1192 	{
       
  1193 	LOG( ESockLog::Printf(_L8("RSubConnection %08x:\tAdd(RSocket id=%d) tid %d"), this, aSocket.SubSessionHandle(), (TUint)RThread().Id()););
       
  1194  	SendReceive(ESCAddSocket, TIpcArgs(aSocket.SubSessionHandle()), aStatus);
       
  1195 	}
       
  1196 
       
  1197 EXPORT_C void RSubConnection::Remove(RSocket& aSocket, TRequestStatus& aStatus)
       
  1198 /** Remove a socket from a subconnection. The socket will be moved back to the default sub-connection.
       
  1199 	The successful completion of this method does not indicate that the socket has moved back to the
       
  1200 	default sub-connection, it only indicates that the move negotiation has been successful. An event
       
  1201 	(via eventNotification) will be sent once the socket is running on the default sub-connection.
       
  1202 
       
  1203 @param aSocket Socket to be removed from the Sub-Connection
       
  1204 @param aStatus Status to complete when socket has been removed (or failed to remove)
       
  1205 @return KErrNone if successful, otherwise a system wide error
       
  1206 */
       
  1207 	{
       
  1208 	LOG( ESockLog::Printf(_L8("RSubConnection %08x:\tRemove(RSocket id=%d) tid %d"), this, aSocket.SubSessionHandle(), (TUint)RThread().Id()););
       
  1209 	SendReceive(ESCRemoveSocket, TIpcArgs(aSocket.SubSessionHandle()), aStatus);
       
  1210 	}
       
  1211 
       
  1212 EXPORT_C TInt RSubConnection::SetParameters(const RSubConParameterBundle& aParameterBundle)
       
  1213 /** Set Parameters of the sub-connection. Successful completion of this method only indicates that
       
  1214     the negotiation has been successfully started. An event via eventNotification) will be sent once
       
  1215 	the granted parameters are available.
       
  1216 
       
  1217 @param aParameterBundle bundle of parameters to be applied to the sub-connection
       
  1218 @return KErrNone if successful, otherwise a system wide error
       
  1219 */
       
  1220 	{
       
  1221 	RParameterFamilyBundle pfb;
       
  1222 	TRAPD(ret,aParameterBundle.CopyToFamilyBundleL(pfb));
       
  1223 	if(ret==KErrNone)
       
  1224 		{
       
  1225 		ret=SetParameters(pfb);
       
  1226 		}
       
  1227 	pfb.Destroy();
       
  1228 	return ret;
       
  1229 	}
       
  1230 
       
  1231 EXPORT_C TInt RSubConnection::GetParameters(RSubConParameterBundle& aParameterBundle)
       
  1232 /** Fetch the sub-connection's current parameters (Requested, Acceptable and Granted)
       
  1233 
       
  1234 @param aParameterBundle bundle of parameters to write the current parameters into
       
  1235 @return KErrNone if successful, otherwise a system wide error
       
  1236 */
       
  1237 	{
       
  1238 	RParameterFamilyBundle pfb;
       
  1239 	TInt ret = GetParameters(pfb);
       
  1240 	if(ret==KErrNone)
       
  1241 		{
       
  1242 		TRAP(ret,aParameterBundle.CopyFromFamilyBundleL(pfb));
       
  1243 		}
       
  1244 	pfb.Destroy();
       
  1245 	return ret;
       
  1246 	}
       
  1247 
       
  1248 EXPORT_C TInt RSubConnection::SetParameters(const RParameterFamilyBundle& aParameterBundle)
       
  1249 /** Set Parameters of the sub-connection. Successful completion of this method only indicates that
       
  1250     the negotiation has been successfully started. An event via eventNotification) will be sent once
       
  1251 	the granted parameters are available.
       
  1252 
       
  1253 @param aParameterBundle bundle of parameters to be applied to the sub-connection
       
  1254 @return KErrNone if successful, otherwise a system wide error
       
  1255 */
       
  1256 	{
       
  1257 	const_cast<RParameterFamilyBundle&>(aParameterBundle).ClearAllParameters(RParameterFamily::EGranted);
       
  1258 
       
  1259 	HBufC8* buffer = HBufC8::New(aParameterBundle.Length());
       
  1260 	if(buffer == NULL)
       
  1261 		{
       
  1262 		return KErrNoMemory;
       
  1263 		}
       
  1264 
       
  1265 	TPtr8 ptr = buffer->Des();
       
  1266 	TInt ret = aParameterBundle.Store(ptr);
       
  1267 	if (ret == KErrNone)
       
  1268 		{
       
  1269 		ret = SendReceive(ESCSetParameters, TIpcArgs(&ptr));
       
  1270 		}
       
  1271 
       
  1272 	delete buffer;
       
  1273 	return ret;
       
  1274 	}
       
  1275 
       
  1276 EXPORT_C TInt RSubConnection::GetParameters(RParameterFamilyBundle& aParameterBundle)
       
  1277 /** Fetch the sub-connection's current parameters (Requested, Acceptable and Granted)
       
  1278 
       
  1279 @param aParameterBundle bundle of parameters to write the current parameters into
       
  1280 @return KErrNone if successful, otherwise a system wide error
       
  1281 */
       
  1282 	{
       
  1283 	TInt lengthOrError = SendReceive(ESCGetParametersLength, TIpcArgs());
       
  1284 	if (lengthOrError < KErrNone)
       
  1285 		{
       
  1286 		return lengthOrError;
       
  1287 		}
       
  1288 
       
  1289 	HBufC8* buffer = HBufC8::New(lengthOrError);
       
  1290 	if (buffer == NULL)
       
  1291 		{
       
  1292 		return KErrNoMemory;
       
  1293 		}
       
  1294 
       
  1295 	TPtr8 ptr = buffer->Des();
       
  1296 	TInt ret = SendReceive(ESCGetParameters, TIpcArgs(&ptr));
       
  1297 	if (ret == KErrNone)
       
  1298 		{
       
  1299 		TRAP(ret,aParameterBundle.LoadL(ptr));
       
  1300 		}
       
  1301 
       
  1302 	delete buffer;
       
  1303 	return ret;
       
  1304 	}
       
  1305 
       
  1306 EXPORT_C void RSubConnection::EventNotification(TNotificationEventBuf& aEventBuffer, TBool aGenericEventsOnly, TRequestStatus& aStatus)
       
  1307 /** Requests asynchronous event notification for the sub-connection.
       
  1308 
       
  1309 @param aEventBuffer A buffer to receive event notification.
       
  1310 @param aStatus On return, the status of the request.
       
  1311 */
       
  1312 	{
       
  1313 	SendReceive(ESCEventAllNotifications, TIpcArgs(&aEventBuffer, aGenericEventsOnly), aStatus);	
       
  1314 	}
       
  1315 
       
  1316 EXPORT_C void RSubConnection::EventNotification(TNotificationEventBuf& aEventBuffer, TEventFilter aEventFilterList[], TUint aEventListLength, TRequestStatus& aStatus)
       
  1317 /** Requests asynchronous notification of a specific list of events for the sub-connection.
       
  1318 
       
  1319 @param aEventBuffer A buffer to receive event notification.
       
  1320 @param aEventFilterList list of event filters specifying a subset of events of interest.
       
  1321 @param aEventListLength Length of the filter list provided
       
  1322 @param aStatus On return, the status of the request.
       
  1323 */
       
  1324 	{
       
  1325 	//Since we are creating the descriptor on the stack we need to ensure that buffer is around for when the reading
       
  1326 	//takes place. We therefore have to upload the buffer synchronously and only then can we ask for the asynchronous
       
  1327 	//notification
       
  1328 	TPtrC8 buffer((const unsigned char*)aEventFilterList, aEventListLength * sizeof(TEventFilter));
       
  1329 	TInt ret = SendReceive(ESCEventNotificationSetup, TIpcArgs(&buffer));
       
  1330 	if (ret == KErrNone)
       
  1331 		{
       
  1332 		SendReceive(ESCEventNotification, TIpcArgs(&aEventBuffer), aStatus);	
       
  1333 		}
       
  1334 	else
       
  1335 		{
       
  1336 		TRequestStatus* statPtr = &aStatus;
       
  1337 		User::RequestComplete(statPtr, ret);
       
  1338 		}	
       
  1339 	
       
  1340 	}
       
  1341 
       
  1342 EXPORT_C void RSubConnection::CancelEventNotification()
       
  1343 /** Cancel an outstanding Event Notification request
       
  1344 */
       
  1345 	{
       
  1346 	SendReceive(ESCEventNotificationCancel);
       
  1347 	}
       
  1348 
       
  1349 EXPORT_C TInt RSubConnection::Control(TUint aOptionLevel, TUint aOptionName, TDes8& aOption)
       
  1350 	{
       
  1351 	return SendReceive(ESCControl, TIpcArgs(aOptionLevel, aOptionName, &aOption));
       
  1352 	}
       
  1353 
       
  1354 TBool RSubConnection::SameSession(TInt aSessionHandle)
       
  1355 /** Checks that the Session Handle passed is the same as that of this RSubConnection.
       
  1356 
       
  1357 Use to verify the RSubConnection argument passed to the RSocket and RHostResolver
       
  1358 Open(..., RSubConnection& aSubConnection) methods.
       
  1359 
       
  1360 @param aSessionHandle The handle which is to be checked against that of this RSubConnection
       
  1361 @returns ETrue if handle is the same, else EFalse
       
  1362 @internalComponent
       
  1363 */
       
  1364 	{
       
  1365 	return (Session().Handle() == aSessionHandle);
       
  1366 	}
       
  1367