networkprotocolmodules/suplprotocolmodule/SuplPushAPI/src/lbssuplpushimpl.cpp
changeset 0 9cfd9a3ee49c
equal deleted inserted replaced
-1:000000000000 0:9cfd9a3ee49c
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Internal implementation of the SUPL Push API
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalComponent
       
    21  @deprecated
       
    22 */
       
    23 
       
    24 #include <e32base.h>
       
    25 #include <centralrepository.h>
       
    26 #include "lbsdevloggermacros.h"
       
    27 
       
    28 #include "lbssuplpushimpl.h"
       
    29 #include "lbssuplpushprops.h"
       
    30 #include "lbssystemcontroller.h"
       
    31 #include "lbsrootcenrepdefs.h"
       
    32 
       
    33 
       
    34 /** The time to live for a message in seconds. After a message is submitted via the SuplInit method,
       
    35 it must be delivered to the SPM in this time. Otherwise, it is failed and 
       
    36 MLbsSuplPushObserver::OnSuplInitComplete with aError==KErrTimedOut is called.*/ 
       
    37 #ifdef TE_LBSSUPLPUSHIMPL_ON
       
    38 const TInt KMsgTimeoutInterval = 5;
       
    39 #else
       
    40 const TInt KMsgTimeoutInterval = 30;
       
    41 #endif //TE_LBSSUPLPUSHIMPL_ON
       
    42 
       
    43 /** Maximumal possible length of the SUPL INIT message. 
       
    44    	This value is bigger and not exactly equal to the real maximal length of an ASN.1 encoded SUPL INIT message.
       
    45    	It is used only for cutting off mailformed extra large SUPL INIT messages. */
       
    46 const TInt KLbsMaxSuplMsgLength = 2048;
       
    47 
       
    48 
       
    49 
       
    50 
       
    51 /**
       
    52 Constructor. 
       
    53 
       
    54 @param aReqId [In] The message unique request id.
       
    55 @param aMsg [In] The message with the request id record in the start of the buffer. The ownership is passed to CLbsSuplPushMsgInfo here.
       
    56 */  
       
    57 CLbsSuplPushMsgInfo::CLbsSuplPushMsgInfo(TInt aReqId, HBufC8* aMsg) :
       
    58 iReqId(aReqId), iMsg(aMsg)	
       
    59 	{
       
    60 	LBSLOG(ELogP1, "CLbsSuplPushMsgInfo::CLbsSuplPushMsgInfo() Begin\n");
       
    61 	LBSLOG(ELogP1, "CLbsSuplPushMsgInfo::CLbsSuplPushMsgInfo() End\n");
       
    62 	}
       
    63 
       
    64 
       
    65 /**
       
    66 Destructor. The iMsg buffer is deleted here.
       
    67 */ 
       
    68 CLbsSuplPushMsgInfo::~CLbsSuplPushMsgInfo()
       
    69 	{
       
    70 	LBSLOG(ELogP1, "CLbsSuplPushMsgInfo::~CLbsSuplPushMsgInfo() Begin\n");
       
    71 	delete iMsg;
       
    72 	LBSLOG(ELogP1, "CLbsSuplPushMsgInfo::~CLbsSuplPushMsgInfo() End\n");
       
    73 	}
       
    74 			
       
    75 
       
    76 /**
       
    77 Creates an instance of the CLbsSuplPushImpl class.
       
    78 
       
    79 @param aChannel [In] The id of the channel to be opened.
       
    80 @param aObserver [In] A reference to an observer waiting for request completion call-backs.
       
    81 
       
    82 @return An instance of the class. The calling application becomes the
       
    83 owner of the returned instance and is responsible its disposal.
       
    84 
       
    85 @see CLbsSuplPush::ConstructL
       
    86 */
       
    87 CLbsSuplPushImpl* CLbsSuplPushImpl::NewL(TLbsSuplPushChannel aChannel, MLbsSuplPushObserver& aObserver)
       
    88 	{
       
    89 	LBSLOG(ELogP1, "CLbsSuplPushImpl::NewL() Begin\n");
       
    90 	CLbsSuplPushImpl* newObj = new (ELeave) CLbsSuplPushImpl(aChannel, aObserver);
       
    91 	CleanupStack::PushL(newObj);
       
    92 	newObj->ConstructL(aChannel);
       
    93 	CleanupStack::Pop(newObj);
       
    94 	LBSLOG(ELogP1, "CLbsSuplPushImpl::NewL() End\n");
       
    95 	return newObj;
       
    96 	}
       
    97 	
       
    98 /**
       
    99 Closes the interface and disposes all open or used resources.
       
   100 */
       
   101 CLbsSuplPushImpl::~CLbsSuplPushImpl()
       
   102 	{
       
   103 	LBSLOG(ELogP1, "CLbsSuplPushImpl::~CLbsSuplPushImpl() Begin\n");
       
   104 	Cancel();
       
   105 	if(iState==EWaitingAck)
       
   106 		{
       
   107 		ReleaseBusyProp();
       
   108 		}
       
   109 	delete iTimer;
       
   110 	
       
   111 	iMsgQueue.ResetAndDestroy();
       
   112 	iAckProperty.Close();
       
   113 	iBusyProperty.Close();
       
   114 	LBSLOG(ELogP1, "CLbsSuplPushImpl::~CLbsSuplPushImpl() End\n");
       
   115 	}
       
   116 	
       
   117 /**
       
   118 Constructor.
       
   119 
       
   120 @param aChannel [In] The id of the channel to be opened.
       
   121 @param aObserver [In] A reference to an observer waiting for request completion call-backs.
       
   122 */
       
   123 CLbsSuplPushImpl::CLbsSuplPushImpl(TLbsSuplPushChannel aChannel, MLbsSuplPushObserver& aObserver):
       
   124 CActive(CActive::EPriorityUserInput),
       
   125 iChannel(aChannel),
       
   126 iState(ECreated),
       
   127 iObserver(aObserver)
       
   128 	{
       
   129 	LBSLOG(ELogP1, "CLbsSuplPushImpl::CLbsSuplPushImpl() Begin\n");
       
   130 	CActiveScheduler::Add(this);
       
   131 	LBSLOG(ELogP1, "CLbsSuplPushImpl::CLbsSuplPushImpl() End\n");
       
   132 	}
       
   133 
       
   134 /**
       
   135 2nd phase constructor. 
       
   136 Creates and assigns all the required internal resources.
       
   137 
       
   138 @param aChannel [In] An id of the channel to be opened.
       
   139 */
       
   140 void CLbsSuplPushImpl::ConstructL(TLbsSuplPushChannel aChannel)
       
   141 	{
       
   142 	LBSLOG(ELogP1, "CLbsSuplPushImpl::ConstructL() Begin\n");
       
   143 	//There are only two channels available currently.
       
   144 	__ASSERT_DEBUG(aChannel==ELbsSuplPushChannelSMS || aChannel==ELbsSuplPushChannelWAP,
       
   145 			User::Invariant());
       
   146 	
       
   147 	if(!(aChannel==ELbsSuplPushChannelSMS || aChannel==ELbsSuplPushChannelWAP))
       
   148 		{
       
   149 		User::Leave(KErrGeneral);
       
   150 		}
       
   151 		
       
   152 	if(aChannel==ELbsSuplPushChannelSMS)
       
   153 		{
       
   154 		iBusyPropKey=KLbsSuplPushSmsBusyKey;
       
   155 		iInitPropKey=KLbsSuplPushSmsInitKey;
       
   156 		iAckPropKey=KLbsSuplPushSmsAckKey;
       
   157 		}
       
   158 	else
       
   159 		{	
       
   160 		iBusyPropKey=KLbsSuplPushWapBusyKey;
       
   161 		iInitPropKey=KLbsSuplPushWapInitKey;
       
   162 		iAckPropKey=KLbsSuplPushWapAckKey;
       
   163 		}
       
   164 	
       
   165 	iTimer = CLbsCallbackTimer::NewL(*this);
       
   166 	LBSLOG(ELogP1, "CLbsSuplPushImpl::ConstructL() End\n");
       
   167 	}
       
   168 
       
   169 /**
       
   170 Provides an internal implementation of CLbsSuplPush::SuplInit
       
   171 
       
   172 @param aReqId [Out] A reference on the TLbsSuplPushRequestId variable where the assigned request id is written.
       
   173 @param aMsg [In] The message buffer.
       
   174 @param aReserved [In] Reserved for future use.
       
   175 
       
   176 @return An error code related to the synchronous part of the request - KErrNone if successful, KErrArgument if 
       
   177 the message has a wrong size, KErrNotReady if the LBS can't be started, KErrPermissionDenied if the calling process
       
   178 has not enough capabilities, or another system error code.
       
   179 
       
   180 @see MLbsSuplPushObserver::OnSuplInitComplete
       
   181 @see CLbsSuplPush::SuplInit
       
   182 */
       
   183 TInt CLbsSuplPushImpl::SuplInit(TLbsSuplPushRequestId& aReqId, const TDesC8& aMsg, TInt /*aReserved*/)
       
   184 	{
       
   185 	LBSLOG(ELogP1, "CLbsSuplPushImpl::ConstructL() Begin\n");
       
   186 	TRAPD(err, SuplInitL(aReqId, aMsg));
       
   187 	LBSLOG(ELogP1, "CLbsSuplPushImpl::ConstructL() End\n");
       
   188 	return err;
       
   189 	}
       
   190 
       
   191 /**
       
   192 A leaving implementation of the CLbsSuplPushImpl::SuplInit. 
       
   193 
       
   194 @param aReqId [Out] A reference on the TLbsSuplPushRequestId variable where the assigned request id is written.
       
   195 @param aMsg [In] The message buffer.
       
   196 
       
   197 @leave If a error happens, it leaves with the correspondent error code.
       
   198 
       
   199 @see CLbsSuplPushImpl::SuplInit
       
   200 */
       
   201 void CLbsSuplPushImpl::SuplInitL(TLbsSuplPushRequestId& aReqId, const TDesC8& aMsg)
       
   202 	{
       
   203 	LBSLOG(ELogP1, "CLbsSuplPushImpl::SuplInitL() Begin\n");
       
   204 	aReqId = 0;
       
   205 	
       
   206 	if(aMsg.Length()>KLbsMaxSuplMsgLength || aMsg.Length()==0)
       
   207 		{
       
   208 		//The messages out of these bounds must not arrive. If they do please check the source of the messages
       
   209 		//and make sure they are correct.
       
   210 		__ASSERT_DEBUG(0, User::Invariant());
       
   211 		User::Leave(KErrArgument);
       
   212 		}
       
   213 	
       
   214 	if(iState==ECreated)
       
   215 		{
       
   216 				
       
   217 		// Get the CategoryUid from the cenrep file owned by LbsRoot.
       
   218 		TInt category;
       
   219 		CRepository* rep = CRepository::NewLC(KLbsCenRepUid);
       
   220 		User::LeaveIfError(rep->Get(KSuplPushAPIKey, category));
       
   221 		CleanupStack::PopAndDestroy(rep);
       
   222 		iPropOwnerSecureId = TUid::Uid(category);
       
   223 		
       
   224 		//Initializing the BUSY property if it was not initialized before
       
   225 		TInt val;
       
   226 		User::LeaveIfError(RProperty::Get(iPropOwnerSecureId, iBusyPropKey, val));
       
   227 		if(val==0)
       
   228 			{
       
   229 			User::LeaveIfError(RProperty::Set(iPropOwnerSecureId, iBusyPropKey, 1));
       
   230 			}
       
   231 		
       
   232 		//Attaching to the BUSY and ACK properties
       
   233 		User::LeaveIfError(iBusyProperty.Attach(iPropOwnerSecureId, iBusyPropKey, EOwnerThread));
       
   234 		User::LeaveIfError(iAckProperty.Attach(iPropOwnerSecureId, iAckPropKey, EOwnerThread));
       
   235 		
       
   236 		iState=EInitialized; 
       
   237 		}
       
   238 		
       
   239 	TBool isBusy;
       
   240 	TInt reqId;
       
   241 	User::LeaveIfError(GetBusyData(isBusy, reqId));
       
   242 	User::LeaveIfError(SetBusyData(isBusy, reqId+1));
       
   243 	
       
   244 	HBufC8* buf=HBufC8::NewL(2*sizeof(TInt)+aMsg.Length());
       
   245 	CleanupStack::PushL(buf);
       
   246 	TPtr8 ptr=buf->Des();
       
   247 	TInt length = aMsg.Length(); 
       
   248 	ptr.Append(TPckgC<TInt>(length));
       
   249 	ptr.Append(TPckgC<TInt>(reqId));
       
   250 	ptr.Append(aMsg);
       
   251 	
       
   252 	CLbsSuplPushMsgInfo* msg = new(ELeave) CLbsSuplPushMsgInfo(reqId, buf);
       
   253 	CleanupStack::Pop(buf);
       
   254 	
       
   255 	CleanupStack::PushL(msg);
       
   256 	iMsgQueue.AppendL(msg);
       
   257 	CleanupStack::Pop(msg);
       
   258 
       
   259 	if(iState==EInitialized)
       
   260 		{
       
   261 		//if not leave, we switch either to EWaitingAck or EWaitingBusy state here
       
   262 		User::LeaveIfError(SendMessage(EFalse)); 		
       
   263 		}
       
   264 	aReqId = reqId;
       
   265 	LBSLOG(ELogP1, "CLbsSuplPushImpl::SuplInitL() End\n");
       
   266 	}
       
   267 
       
   268 
       
   269 /**
       
   270 Tries to send the next message in the queue. If the channel is busy, it subscribes for the BUSY property
       
   271 and wait asynchronously when the property is free.
       
   272 
       
   273 @param aNotifyObserver [In] If the function must notify the observer when a error happens and the message fails.
       
   274 
       
   275 @return A error code if error happens, KErrNone - otherwise.
       
   276 
       
   277 @see CLbsSuplPushImpl::SuplInitL
       
   278 @see CLbsSuplPushImpl::OnTimerEventL
       
   279 @see CLbsSuplPushImpl::RunL
       
   280 */
       
   281 TInt CLbsSuplPushImpl::SendMessage(TBool aNotifyObserver)
       
   282 	{
       
   283 	LBSLOG(ELogP1, "CLbsSuplPushImpl::SendMessage() Begin\n");
       
   284 	//A message can be sent only when we are in the EInitialized state. And it must be in the queue, so the queue
       
   285 	//can't be empty.
       
   286 	__ASSERT_DEBUG(iState==EInitialized && iMsgQueue.Count()>0, User::Invariant());	
       
   287 		
       
   288 	CLbsSuplPushMsgInfo* msg=iMsgQueue[0];
       
   289 	TBool isBusy;
       
   290 	TInt reqId;
       
   291 	
       
   292 	TInt err = GetBusyData(isBusy, reqId);
       
   293 	if(err==KErrNone)
       
   294 		{
       
   295 		if(isBusy)
       
   296 			{
       
   297 			iBusyProperty.Subscribe(iStatus);
       
   298 			SetActive();
       
   299 			iState = EWaitingBusy;
       
   300 			LBSLOG(ELogP1, "CLbsSuplPushImpl::SendMessage() End\n");
       
   301 			return KErrNone;
       
   302 			}
       
   303 	
       
   304 		iAckProperty.Subscribe(iStatus);
       
   305 		SetActive();
       
   306 	
       
   307 		err = RProperty::Set(iPropOwnerSecureId, iInitPropKey, *msg->iMsg);
       
   308 		if(err==KErrNone)
       
   309 			{
       
   310 			err=SetBusyData(ETrue, reqId);
       
   311 			if(err==KErrNone)
       
   312 				{
       
   313 				iState=EWaitingAck;
       
   314 				iTimer->EventAfter(TTimeIntervalSeconds(KMsgTimeoutInterval), 0);
       
   315 				LBSLOG(ELogP1, "CLbsSuplPushImpl::SendMessage() End\n");
       
   316 				return KErrNone;
       
   317 				}
       
   318 			}
       
   319 		//err!=KErrNone)
       
   320 		Cancel();
       
   321 		}
       
   322 	
       
   323 	//err!=KErrNone)
       
   324 	if(aNotifyObserver)
       
   325 		{
       
   326 		iObserver.OnSuplInitComplete(iChannel, msg->iReqId, err, 0);
       
   327 		LBSLOG(ELogP9, "<-S MLbsSuplPushObserver::OnSuplInitComplete() SuplPush\n");
       
   328 		LBSLOG2(ELogP9, "  > TLbsSuplPushChannel aChannel = %d\n", iChannel);
       
   329 		LBSLOG2(ELogP9, "  > TLbsSuplPushRequestId aReqId = %d\n", msg->iReqId);
       
   330 		LBSLOG2(ELogP9, "  > TInt aError = %d\n", err);
       
   331 		}
       
   332 	iMsgQueue.Remove(0);
       
   333 	delete msg;
       
   334 	LBSLOG(ELogP1, "CLbsSuplPushImpl::SendMessage() End\n");
       
   335 	return err;
       
   336 	}
       
   337 
       
   338 /**
       
   339 From MLbsCallbackTimerObserver. Called when a message timeout error happens. It removes the outdated message 
       
   340 from the queue, notifies the observer that that message fails. Then it tries to deliver the next message if there is any.
       
   341 If there is no messages to deliver and the object is in the EWaitingBusy state, it unsubscribes 
       
   342 from the BUSY property.
       
   343 
       
   344 @see CLbsCallbackTimer
       
   345 @see CLbsSuplPushImpl::OnTimerError
       
   346 */
       
   347 void CLbsSuplPushImpl::OnTimerEventL(TInt /*aTimerId*/)
       
   348 	{
       
   349 	LBSLOG(ELogP1, "CLbsSuplPushImpl::SendMessage() Begin\n");
       
   350 	//A timer event can occur only when we are trying to deliver a message. That is we must be in 
       
   351 	//EWaitingAck state.
       
   352 	__ASSERT_DEBUG((iMsgQueue.Count()>0 && iState==EWaitingAck), User::Invariant());
       
   353 			
       
   354 	//Remove the expired message from the queue and notify the observer
       
   355 	CLbsSuplPushMsgInfo* msg=iMsgQueue[0];
       
   356 	iObserver.OnSuplInitComplete(iChannel, msg->iReqId, KErrTimedOut, 0);
       
   357 	LBSLOG(ELogP9, "<-S MLbsSuplPushObserver::OnSuplInitComplete() SuplPush\n");
       
   358 	LBSLOG2(ELogP9, "  > TLbsSuplPushChannel aChannel = %d\n", iChannel);
       
   359 	LBSLOG2(ELogP9, "  > TLbsSuplPushRequestId aReqId = %d\n", msg->iReqId);
       
   360 	LBSLOG(ELogP9, "  > TInt aError = KErrTimedOut\n");
       
   361 	delete msg;
       
   362 	iMsgQueue.Remove(0);
       
   363 	
       
   364 	
       
   365 		
       
   366 	//end the ACK subscription
       
   367 	Cancel();
       
   368 			
       
   369 	//Release the BUSY property. 
       
   370 	//The iState is set to EInitialized
       
   371 	ReleaseBusyProp(); 
       
   372 			
       
   373 	//Schedule the next timeout event and start to deliver next message
       
   374 	while(iMsgQueue.Count()>0)
       
   375 		{
       
   376 		//The message is deleted in the SendMessage if the sending attempt fails
       
   377 		if(SendMessage(ETrue)==KErrNone)
       
   378 			{
       
   379 			break;
       
   380 			}
       
   381 		}
       
   382 	LBSLOG(ELogP1, "CLbsSuplPushImpl::SendMessage() End\n");
       
   383 	}
       
   384 
       
   385 
       
   386 /**
       
   387 Called either when in the EWaitingAck state and  the ACK property is changed or when in the EWaitingBusy
       
   388 state and the BUSY property is changed. 
       
   389 
       
   390 In the EWaitingAck state it checks that it is really the notification on 
       
   391 the message delivering now. If it is, it notifies the observer about the successful delivery. If not,
       
   392 it resubscribes, returns immediately and the object continues to wait for the correct notification 
       
   393 asynchronously.
       
   394 
       
   395 In the EWaitingBusy state it checks if the channel is free. If it is not, it resubscribes, returns immideatelly,
       
   396 and the object continues to wait when the channel is free asynchronously.
       
   397 
       
   398 In both states if the object is in the EInitialized state and ready to deliver the next message, the function
       
   399 tries to deliver the message if there is any.
       
   400 
       
   401 @leave The function does not leave despite it has the L suffix. So, we do not need to imlement 
       
   402 the CActive::RunError function.
       
   403 
       
   404 @see CActive::RunL
       
   405 */
       
   406 /*virtual*/ void CLbsSuplPushImpl::RunL()
       
   407 	{
       
   408 	LBSLOG(ELogP1, "CLbsSuplPushImpl::SendMessage() Begin\n");
       
   409 	//The asyncronous request can be only either in EWaitingAck or EWaitingBusy state.
       
   410 	__ASSERT_DEBUG(iState==EWaitingAck || iState==EWaitingBusy, User::Invariant());
       
   411 	if(EWaitingAck==iState)
       
   412 		{
       
   413 		//At least the message being delivered must be in the queue.
       
   414 		__ASSERT_DEBUG(iMsgQueue.Count()>0, User::Invariant());
       
   415 			
       
   416 		CLbsSuplPushMsgInfo* msg = iMsgQueue[0];			
       
   417 		TInt err = iStatus.Int();
       
   418 		if(err==KErrNone)
       
   419 			{
       
   420 			TInt ack;
       
   421 			err=RProperty::Get(iPropOwnerSecureId, iAckPropKey, ack);
       
   422 			if(err==KErrNone && ack!=msg->iReqId) 
       
   423 				{
       
   424 				//It was not our message. It must not happen.
       
   425 				__ASSERT_DEBUG(0, User::Invariant());
       
   426 				//We continue to listen for our message
       
   427 				iAckProperty.Subscribe(iStatus);
       
   428 				SetActive();
       
   429 				LBSLOG(ELogP1, "CLbsSuplPushImpl::SendMessage() End\n");
       
   430 				return;
       
   431 				}
       
   432 			}
       
   433 
       
   434 		iObserver.OnSuplInitComplete(iChannel, msg->iReqId, err, 0);
       
   435 		LBSLOG(ELogP9, "<-S MLbsSuplPushObserver::OnSuplInitComplete() SuplPush\n");
       
   436 		LBSLOG2(ELogP9, "  > TLbsSuplPushChannel aChannel = %d\n", iChannel);
       
   437 		LBSLOG2(ELogP9, "  > TLbsSuplPushRequestId aReqId = %d\n", msg->iReqId);
       
   438 		LBSLOG2(ELogP9, "  > TInt aError = %d\n", err);
       
   439 			
       
   440 		delete msg;
       
   441 		iMsgQueue.Remove(0);
       
   442 		ReleaseBusyProp();
       
   443 		iTimer->Cancel();  //cancel timeout event here
       
   444 		
       
   445 		}
       
   446 	else//	EWaitingBusy:
       
   447 		{
       
   448 		TBool isBusy;
       
   449 		TInt reqId;
       
   450 		TInt err= GetBusyData(isBusy, reqId);
       
   451 		if(err!=KErrNone || isBusy) //Still waiting
       
   452 			{
       
   453 			iBusyProperty.Subscribe(iStatus);
       
   454 			SetActive();
       
   455 			LBSLOG(ELogP1, "CLbsSuplPushImpl::SendMessage() End\n");
       
   456 			return;
       
   457 			}
       
   458 		iState = EInitialized;
       
   459 		}
       
   460 	
       
   461 	//If there's been no error, we must be ready for sending messages and switch to EInitialized state.
       
   462 	__ASSERT_DEBUG(EInitialized == iState, User::Invariant());
       
   463 	
       
   464 	//Start to deliver next message
       
   465 	while(iMsgQueue.Count()>0)
       
   466 		{
       
   467 		//The message is deleted in the SendMessage if the sending attempt fails
       
   468 		if(SendMessage(ETrue)==KErrNone)
       
   469 			{
       
   470 			break;
       
   471 			}
       
   472 		}
       
   473 	
       
   474 	LBSLOG(ELogP1, "CLbsSuplPushImpl::SendMessage() End\n");
       
   475 	}
       
   476 	
       
   477 /**
       
   478 Called when CActive::Cancel method is called. It cancels both the ACK and BUSY subscriptions. Only one of
       
   479 the two subscriptions can be actually active at every moment. But it is harmless to cancel inactive
       
   480 subscription.
       
   481 
       
   482 @see CActive::DoCancel
       
   483 @see CLbsSuplPushImpl::~CLbsSuplPushImpl
       
   484 @see CLbsSuplPushImpl::SendMessage
       
   485 @see CLbsSuplPushImpl::OnTimerEventL
       
   486 */
       
   487 /*virtual*/ void CLbsSuplPushImpl::DoCancel()
       
   488 	{
       
   489 	LBSLOG(ELogP1, "CLbsSuplPushImpl::SendMessage() Begin\n");
       
   490 	if(iState!=ECreated)
       
   491 		{
       
   492 		iAckProperty.Cancel();
       
   493 		iBusyProperty.Cancel();
       
   494 		}
       
   495 	LBSLOG(ELogP1, "CLbsSuplPushImpl::SendMessage() End\n");
       
   496 	}
       
   497 
       
   498 /**
       
   499 Tries to release the BUSY property. Switches to the EInitialized state in any case even though a error happens.
       
   500 
       
   501 @return A error code if error happens, KErrNone - otherwise.
       
   502 
       
   503 @see CLbsSuplPushImpl::~CLbsSuplPushImpl
       
   504 @see CLbsSuplPushImpl::OnTimerEventL
       
   505 @see CLbsSuplPushImpl::RunL
       
   506 */
       
   507 TInt CLbsSuplPushImpl::ReleaseBusyProp()
       
   508 	{
       
   509 	LBSLOG(ELogP1, "CLbsSuplPushImpl::ReleaseBusyProp() Begin\n");
       
   510 	//We must have grabbed the BUSY property before trying to release it.
       
   511 	__ASSERT_DEBUG(iState==EWaitingAck, User::Invariant());
       
   512 	
       
   513 	TBool isBusy;
       
   514 	TInt reqId;
       
   515 	TInt err=GetBusyData(isBusy, reqId);
       
   516 	if(err==KErrNone)
       
   517 		{
       
   518 		//As we have grabbed the BUSY property, it must be in the BUSY state.
       
   519 		__ASSERT_DEBUG(isBusy, User::Invariant());
       
   520 		err=SetBusyData(EFalse, reqId);
       
   521 		}
       
   522 	
       
   523 	if(err!=KErrNone)
       
   524 		{
       
   525 		//We do not expect any environment errors here. The properties must be in correct state and
       
   526 		//RProperty::Get & Set methods must not fail here.
       
   527 		__ASSERT_DEBUG(0, User::Invariant());
       
   528 		}
       
   529 	
       
   530 	//We switch to EInitialized, even though error happened and we failed to release the BUSY property
       
   531 	iState = EInitialized;
       
   532 	
       
   533 	LBSLOG(ELogP1, "CLbsSuplPushImpl::ReleaseBusyProp() End\n");
       
   534 	return err;
       
   535 	}
       
   536 
       
   537 
       
   538 /**
       
   539 Reads the busy flag and the next free request id from the BUSY property.
       
   540 
       
   541 @param aBusy [Out] The busy flag.
       
   542 @param aChannel [Out] The next free request id.
       
   543 
       
   544 @return A error code if error happens, KErrNone - otherwise.
       
   545 
       
   546 @see CLbsSuplPushImpl::SuplInitL
       
   547 @see CLbsSuplPushImpl::SendMessage
       
   548 @see CLbsSuplPushImpl::ReleaseBusyProp
       
   549 */
       
   550 TInt CLbsSuplPushImpl::GetBusyData(TBool& aBusy, TInt& aNextReqId) const
       
   551 	{
       
   552 	LBSLOG(ELogP1, "CLbsSuplPushImpl::GetBusyData() Begin\n");
       
   553 	TInt val;
       
   554 	TInt err = RProperty::Get(iPropOwnerSecureId, iBusyPropKey, val);
       
   555 	if(err!=KErrNone)
       
   556 		{
       
   557 		LBSLOG(ELogP1, "CLbsSuplPushImpl::GetBusyData() End\n");
       
   558 		return err;
       
   559 		}
       
   560 	
       
   561 	if(val>0)
       
   562 		{
       
   563 		aNextReqId = val;
       
   564 		aBusy = EFalse;	
       
   565 		}
       
   566 	else if(val<0)
       
   567 		{
       
   568 		aNextReqId = -val;
       
   569 		aBusy = ETrue;	
       
   570 		}
       
   571 	
       
   572 	else 
       
   573 		{
       
   574 		//val==0. This must not happen - the property is initialized with positive value and then is changed by our
       
   575 		//code only to either postive or negative values.
       
   576 		__ASSERT_DEBUG(0, User::Invariant());
       
   577 		LBSLOG(ELogP1, "CLbsSuplPushImpl::GetBusyData() End\n");
       
   578 		return KErrGeneral;
       
   579 		}
       
   580 	LBSLOG(ELogP1, "CLbsSuplPushImpl::GetBusyData() End\n");
       
   581 	return KErrNone;
       
   582 	}
       
   583 
       
   584 
       
   585 /**
       
   586 Writes the busy flag and the next free request id from the BUSY property.
       
   587 
       
   588 @param aBusy [In] The busy flag.
       
   589 @param aChannel [In] The next free request id.
       
   590 
       
   591 @return A error code if error happens, KErrNone - otherwise.
       
   592 
       
   593 @see CLbsSuplPushImpl::SuplInitL
       
   594 @see CLbsSuplPushImpl::SendMessage
       
   595 @see CLbsSuplPushImpl::ReleaseBusyProp
       
   596 */
       
   597 TInt CLbsSuplPushImpl::SetBusyData(TBool aBusy, TInt aNextReqId) const
       
   598 	{
       
   599 	LBSLOG(ELogP1, "CLbsSuplPushImpl::SetBusyData() Begin\n");
       
   600 	//The BUSY property must not be already grabbed.
       
   601 	__ASSERT_DEBUG(aNextReqId>0, User::Invariant());
       
   602 	
       
   603 	//reseting to one and start from the very beginning
       
   604 	if(aNextReqId==KMaxTInt)
       
   605 		{
       
   606 		aNextReqId=1;
       
   607 		}
       
   608 		
       
   609 	TInt val=aNextReqId;
       
   610 	if(aBusy)
       
   611 		{
       
   612 		val=-val;
       
   613 		}
       
   614 	LBSLOG(ELogP1, "CLbsSuplPushImpl::SetBusyData() End\n");
       
   615 	return RProperty::Set(iPropOwnerSecureId, iBusyPropKey, val);
       
   616 	}
       
   617 
       
   618 /**
       
   619 From MLbsCallbackTimerObserver. Normally it is called when OnTimerEventL leaves. Our implementation 
       
   620 of OnTimerEventL does not leave, so this function must not be called.
       
   621 
       
   622 @see MLbsCallbackTimerObserver
       
   623 @see CLbsCallbackTimer
       
   624 */
       
   625 TInt CLbsSuplPushImpl::OnTimerError(TInt /*aTimerId*/, TInt /*aError*/)
       
   626 	{
       
   627 	LBSLOG(ELogP1, "CLbsSuplPushImpl::SetBusyData() Begin\n");
       
   628 	__ASSERT_DEBUG(0, User::Invariant());
       
   629 	LBSLOG(ELogP1, "CLbsSuplPushImpl::SetBusyData() End\n");
       
   630 	return KErrNone;
       
   631 	}
       
   632 
       
   633 
       
   634