telephonyprotocols/pdplayer/src/mbmsengine.cpp
changeset 0 3553901f7fa8
child 15 fc69e1e37771
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @internalComponent
       
    19 */
       
    20 
       
    21 #include "mbmsengine.h"
       
    22 #include "pdpservices.h"
       
    23 #include <commsdattypesv1_1.h>
       
    24 
       
    25 using namespace ESock;
       
    26 using namespace ConnectionServ;
       
    27 using namespace CommsDat;
       
    28 using namespace Messages;
       
    29 
       
    30 //This function retrieves the phone information.
       
    31 void GetPhoneInfoL(RTelServer& aTelServer, const TDesC& aLoadedTsyName, RTelServer::TPhoneInfo& aInfo);
       
    32 
       
    33 //Constructor for CMBMSEngine
       
    34 CMBMSEngine::CMBMSEngine(const TNodeId& aMbmsTMCommsId, MPacketServiceNotifier& aPacketServiceNotifier)
       
    35 	:CActive(EPriorityStandard),
       
    36 	iMbmsTMCommsId(aMbmsTMCommsId),
       
    37 	iPacketServiceNotifier(aPacketServiceNotifier)
       
    38 	{
       
    39 	CActiveScheduler::Add(this);
       
    40 	}
       
    41 
       
    42 /**
       
    43 The NewL factory function for CMBMSEngine.
       
    44 @param aMBMSTMCommsId comms Id.
       
    45 @param aClientId Node Channel Id.
       
    46 @param aRequestType Message Id
       
    47 @param aRequestBundleOwner Parameter Bundle.
       
    48 @return CMBMSEngine*
       
    49 */
       
    50 CMBMSEngine* CMBMSEngine::NewL(const TNodeId& aMbmsTMCommsId, MPacketServiceNotifier& aPacketServiceNotifier)
       
    51 	{
       
    52 	CMBMSEngine* self = new(ELeave) CMBMSEngine(aMbmsTMCommsId, aPacketServiceNotifier);
       
    53 	CleanupStack::PushL(self);
       
    54 	self->ConstructL();
       
    55 	CleanupStack::Pop(self);
       
    56 	return self;
       
    57 	}
       
    58 
       
    59 /**
       
    60 Destructor for CMBMSEngine.
       
    61 */
       
    62 CMBMSEngine::~CMBMSEngine()
       
    63 	{
       
    64 	iPacketService.Close();
       
    65 	iPhone.Close();
       
    66 	iTelServer.Close();
       
    67 
       
    68 	iMBMSRequestList.ResetAndDestroy();
       
    69 	}
       
    70 /**
       
    71 ConstructL for CMBMSEngine.
       
    72 */
       
    73 void CMBMSEngine::ConstructL()
       
    74 	{
       
    75 	InitialisePhoneL();
       
    76 	iPendingRequests = EFalse;
       
    77 	}
       
    78 /**
       
    79 This function is used to find the MBMS request from the list based on the client Id.
       
    80 @param aClientId The reference to TCFNodeChannelId
       
    81 @return TUint
       
    82 */
       
    83 TUint CMBMSEngine::GetRequestElementL(const TRuntimeCtxId& aNodeCtxId)
       
    84 	{
       
    85 	TBool findMBMSRequest = EFalse;
       
    86 	TInt index = 0;
       
    87 	for (;index < iMBMSRequestList.Count(); index++)
       
    88 		{
       
    89 		if(aNodeCtxId == iMBMSRequestList[index]->GetClientId())
       
    90 			{
       
    91 			findMBMSRequest = ETrue;
       
    92 			break;
       
    93 		    }
       
    94 		}
       
    95 	if(!findMBMSRequest)
       
    96 	   User::Leave(KErrNotFound);
       
    97 
       
    98 	return index;
       
    99 	}
       
   100 
       
   101 /**
       
   102 This function is used to remove requests from the list.
       
   103 @param aClientId The  reference to TCFNodeChannelId
       
   104 @return void
       
   105 */
       
   106 void CMBMSEngine::RemoveFromRequestListL(const Messages::TRuntimeCtxId& aNodeCtxId)
       
   107 	{
       
   108 	TUint index = GetRequestElementL(aNodeCtxId);
       
   109 	DeleteIndexElement(index);
       
   110 	}
       
   111 /**
       
   112 This function is used to delete the request object fron the indexed list.
       
   113 @param aIndex TUint
       
   114 @return void
       
   115 */
       
   116 void CMBMSEngine::DeleteIndexElement(TUint aIndex)
       
   117 	{
       
   118 	delete iMBMSRequestList[aIndex];
       
   119 	iMBMSRequestList[aIndex] = NULL;
       
   120 	iMBMSRequestList.Remove(aIndex);
       
   121     iMBMSRequestList.Compress();
       
   122 
       
   123     //check for any pending requests
       
   124 	CheckPendingRequests();
       
   125 	}
       
   126 
       
   127 /**
       
   128 This function is used to cancel any outstanding request and remove it from the list.
       
   129 @param aClientId The  reference to TCFNodeChannelId
       
   130 @return void
       
   131 */
       
   132 void CMBMSEngine::CancelAndRemoveFromRequestListL(const Messages::TRuntimeCtxId& aNodeCtxId)
       
   133 	{
       
   134 	TUint index = GetRequestElementL(aNodeCtxId);
       
   135 	iMBMSRequestList[index]->CancelMessage(KErrCancel);
       
   136 	DeleteIndexElement(index);
       
   137 	}
       
   138 
       
   139 /**
       
   140 This function is used to check whether any outstanding requests are there or not.
       
   141 In case if any outstanding requests are there,active the requests at the head of the list.
       
   142 @return void
       
   143 */
       
   144 void CMBMSEngine::CheckPendingRequests()
       
   145 	{
       
   146 	if((iMBMSRequestList.Count() > 0) && (!iMBMSRequestList[0]->IsActive()))
       
   147 	 	{
       
   148 		//activate the requests at the head of the list.
       
   149 		iMBMSRequestList[0]->StartRequest();
       
   150 		}
       
   151 	}
       
   152 
       
   153 /**
       
   154 This function is used to check whether the MBMS query is valid or not.If valid,
       
   155 create an object of CMBMSServiceRequest and store in a list for later use.
       
   156 @param aCFMessage The  reference to Messages::TSignatureBase
       
   157 @return void
       
   158 */
       
   159 void CMBMSEngine::AddToRequestListL(
       
   160 		Messages::RNodeInterface* aNodeInterface,
       
   161 		const Messages::TRuntimeCtxId& aNodeCtxId,
       
   162 		const Messages::TNodeSignal::TMessageId& aRequestType,
       
   163 		CRefCountOwnedParameterBundle* aRequestBundleOwner
       
   164 			)
       
   165 	{
       
   166 	TUint mbmsQueryCount = 0;
       
   167 	//the below enums are initialised to EBearerAvailability to avoid Armv5 warnings.
       
   168 	XMBMSServiceQuerySet::TQueryType previousQuery = XMBMSServiceQuerySet::EBearerAvailability ;
       
   169 	XMBMSServiceQuerySet::TQueryType currentQuery  = XMBMSServiceQuerySet::EBearerAvailability;
       
   170 
       
   171 	const ConnectionServ::CConnectionServParameterBundle* mbmsParamsBundle1 = static_cast<const CConnectionServParameterBundle*>(aRequestBundleOwner->Ptr());
       
   172 	if(!mbmsParamsBundle1)
       
   173 	   User::Leave(KErrNotFound);
       
   174 
       
   175 	ConnectionServ::CConnectionServParameterBundle* mbmsParamsBundle = const_cast<CConnectionServParameterBundle *>(mbmsParamsBundle1);
       
   176 
       
   177     //get the cout of Containers
       
   178 	TUint containerCount = mbmsParamsBundle->CountParamSetContainers();
       
   179 
       
   180 	//leave if Container is empty
       
   181 	if (containerCount == 0)
       
   182 		{
       
   183 		User::Leave(KErrArgument);
       
   184 		}
       
   185 
       
   186 	TBool checkMBMSQuery = EFalse;
       
   187 	for(TUint i = 0; i < containerCount; i++)
       
   188 		{
       
   189 		CParameterSetContainer* objectPSC = mbmsParamsBundle->GetParamSetContainer(i);
       
   190 		XMBMSServiceQuerySet* queryMBMS = XMBMSServiceQuerySet::FindInParamSetContainer(*objectPSC);
       
   191 
       
   192 		//pick only MBMS Query Types.
       
   193 		if(!queryMBMS)
       
   194 		   continue;
       
   195 
       
   196 		if(queryMBMS)
       
   197 		   checkMBMSQuery = ETrue;
       
   198 
       
   199 		//leave if there are more than one type of MBMS query in the bundle.
       
   200 		currentQuery = queryMBMS->GetQueryType();
       
   201 		//leave if query is not set.
       
   202 		if(currentQuery<0)
       
   203 		  User::Leave(KErrArgument);
       
   204 
       
   205 		//check whether the bundle has got only MBMS queries.
       
   206 		if(mbmsQueryCount>0)
       
   207 		  {
       
   208 		  if(currentQuery != previousQuery)
       
   209 		   	{
       
   210 		   	User::Leave(KErrArgument);
       
   211 		   	}
       
   212 		  }
       
   213 		previousQuery = currentQuery;
       
   214 		mbmsQueryCount++;
       
   215 		}
       
   216 	//leave if no MBMS query found.
       
   217 	if(!checkMBMSQuery)
       
   218 	  User::Leave(KErrArgument);
       
   219 
       
   220 	//store the CMBMSServiceRequest in a list.
       
   221 	CMBMSServiceRequest* newServiceRequest = CMBMSServiceRequest::NewL(
       
   222 			*this,
       
   223 			iMbmsTMCommsId,
       
   224 			aNodeInterface,
       
   225 			aNodeCtxId,
       
   226 			aRequestType,
       
   227 			aRequestBundleOwner,
       
   228 			currentQuery
       
   229 			);
       
   230 	CleanupStack::PushL(newServiceRequest);
       
   231 	iMBMSRequestList.AppendL(newServiceRequest);
       
   232 	CleanupStack::Pop(newServiceRequest);
       
   233 
       
   234 	//start the requests if none of the requests are pending.
       
   235 	CheckPendingRequests();
       
   236 	}
       
   237 /**
       
   238 Function to initialize the phone settings
       
   239 @return TBool
       
   240 */
       
   241 TBool CMBMSEngine::InitialisePhoneL()
       
   242 	{
       
   243 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   244 	CMDBSession* dbSession = CMDBSession::NewL(KCDVersion1_2);
       
   245 #else
       
   246 	CMDBSession* dbSession = CMDBSession::NewL(KCDVersion1_1);
       
   247 #endif
       
   248     CleanupStack::PushL(dbSession);
       
   249 
       
   250 	CMDBRecordSet<CCDGlobalSettingsRecord> globalSettingsRecord(KCDTIdGlobalSettingsRecord);
       
   251     TRAPD(err, globalSettingsRecord.LoadL(*dbSession));
       
   252     if(err != KErrNone)
       
   253       {
       
   254       User::Leave(KErrNotFound);
       
   255       }
       
   256 
       
   257     CCDModemBearerRecord *modemBearerRecord = static_cast<CCDModemBearerRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdModemBearerRecord));
       
   258     CleanupStack::PushL(modemBearerRecord);
       
   259 
       
   260     modemBearerRecord->SetRecordId(((CCDGlobalSettingsRecord*)globalSettingsRecord.iRecords[0])->iModemForPhoneServicesAndSMS);
       
   261     TRAPD(err1,modemBearerRecord->LoadL(*dbSession));
       
   262 
       
   263     if(err1 != KErrNone)
       
   264       {
       
   265       User::Leave(KErrNotFound);
       
   266       }
       
   267 
       
   268     TName tsyName;
       
   269     tsyName = modemBearerRecord->iTsyName;
       
   270     //leave if not able to read Tsy name.
       
   271     if(tsyName.Length() == 0)
       
   272 	  {
       
   273       User::Leave(KErrNotFound);
       
   274 	  }
       
   275 
       
   276     CleanupStack::PopAndDestroy(modemBearerRecord);
       
   277     CleanupStack::PopAndDestroy(dbSession);
       
   278 
       
   279     User::LeaveIfError(iTelServer.Connect());
       
   280 	User::LeaveIfError(iTelServer.LoadPhoneModule(tsyName));
       
   281 	User::LeaveIfError(iTelServer.SetExtendedErrorGranularity(RTelServer::EErrorExtended));
       
   282 
       
   283 	//Open telephony server
       
   284 	GetPhoneInfoL(iTelServer,tsyName,iPhoneInfo);
       
   285 
       
   286 	//Open phone
       
   287 	User::LeaveIfError(iPhone.Open(iTelServer,iPhoneInfo.iName));
       
   288 	//Get phone status
       
   289 	iPhone.GetStatus(iPhoneStatus);
       
   290 
       
   291 	SetActive();
       
   292 	iPhoneState = EInitialising;
       
   293 
       
   294 	TRequestStatus* status = &iStatus;
       
   295 	User::RequestComplete(status, KErrNone);
       
   296 
       
   297 	return ETrue;
       
   298 	}
       
   299 
       
   300 /**
       
   301 This is CActive overloaded function.Cancel all outstanding requests.
       
   302 @param None
       
   303 @return Void
       
   304 */
       
   305 void CMBMSEngine::DoCancel()
       
   306 	{
       
   307     iPhone.InitialiseCancel();
       
   308 	}
       
   309 
       
   310 /**
       
   311 This is CActive overloaded function.
       
   312 @param None
       
   313 @return TInt
       
   314 */
       
   315 TInt CMBMSEngine::RunError(TInt /*aError*/)
       
   316 	{
       
   317 	Cancel();
       
   318 	return KErrNone;
       
   319 	}
       
   320 
       
   321 /**
       
   322 This is CActive overloaded function.
       
   323 @param None
       
   324 @return Void
       
   325 */
       
   326 void CMBMSEngine::RunL()
       
   327 	{
       
   328 	TRequestStatus* status = &iStatus;
       
   329 	if (iStatus == KErrNone)
       
   330 		{
       
   331 		switch(iPhoneState)
       
   332 			{
       
   333 			case EInitialising:
       
   334 				if(iPhoneStatus.iMode==RPhone::EModeUnknown)
       
   335 					{
       
   336 					iPhone.Initialise(iStatus);
       
   337 					}
       
   338 				else
       
   339 					{
       
   340 					User::RequestComplete(status, KErrNone);
       
   341 					}
       
   342 				SetActive();
       
   343 				iPhoneState = ESetAttachMode;
       
   344 			break;
       
   345 	       	case ESetAttachMode:
       
   346 				//Open packet service
       
   347 				User::LeaveIfError(iPacketService.Open(iPhone));
       
   348 
       
   349 				//Put phone is attachwhenpossible mode.
       
   350 				//In this mode, the phone will try to attach to the gprs network whenever it can.
       
   351 				iPacketService.SetAttachMode(iStatus, RPacketService::EAttachWhenNeeded);
       
   352 				iPhoneState = EAttachModeComplete;
       
   353 				SetActive();
       
   354 			break;
       
   355 			case EAttachModeComplete:
       
   356 			iPacketServiceNotifier.PacketServiceAttachedCallbackL();
       
   357 			break;
       
   358 			}
       
   359 		}
       
   360 	}
       
   361 
       
   362 /**
       
   363 Function to retrieve the RPacketService Instance
       
   364 @return RPacketService&
       
   365 */
       
   366 RPacketService& CMBMSEngine::GetRPacketService()
       
   367 	{
       
   368 	return iPacketService;
       
   369 	}