smsprotocols/smsstack/wapprot/Src/ws_prvdr.cpp
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
child 42 3adadc800673
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     1 // Copyright (c) 1999-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 // Implements CWapSmsProvider and CWapSmsProviderWrite
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20 */
       
    21 
       
    22 #include <e32std.h>
       
    23 #include <wap_sock.h>
       
    24 #include "ws_main.h"
       
    25 #include "es_wsms.h"
       
    26 #include "WAPDGRM.H"
       
    27 #include "ws_obsvr.h"
       
    28 #include "smsprot.h"
       
    29 #include <es_mbuf.h>
       
    30 
       
    31 //
       
    32 // implementation of CWapSmsProvider
       
    33 //
       
    34 
       
    35 	// CWapSmsProvider policies
       
    36 	static _LIT_SECURITY_POLICY_C1(wapSmsProviderSetLocalNamePolicy, ECapabilityNetworkServices );
       
    37 	static _LIT_SECURITY_POLICY_C1(wapSmsProviderSetOptionPolicy, ECapability_None);
       
    38 	static _LIT_SECURITY_POLICY_C1(wapSmsProviderGetLengthIoctlPolicy,ECapability_None);
       
    39 	static _LIT_SECURITY_POLICY_C1(wapSmsProviderGetMessageParamLengthIoctlPolicy,ECapability_None);
       
    40 	static _LIT_SECURITY_POLICY_C1(wapSmsProviderGetMessageParametersIoctlPolicy,ECapabilityReadDeviceData);
       
    41 	static _LIT_SECURITY_POLICY_C1(wapSmsProviderWritePolicy,ECapabilityNetworkServices);
       
    42 
       
    43 
       
    44 /**
       
    45  *  Factory
       
    46  */
       
    47 CWapSmsProvider* CWapSmsProvider::NewL(CWapSmsProtocol* aProtocol)
       
    48 	{
       
    49 	LOGWAPPROT1("CWapSmsProvider::NewL()");
       
    50 
       
    51 	CWapSmsProvider* provider=new(ELeave) CWapSmsProvider(aProtocol);
       
    52 	CleanupStack::PushL(provider);
       
    53 	provider->iWapSmsProviderWrite = CWapSmsProviderWrite::NewL(*provider);
       
    54 	CleanupStack::Pop();
       
    55 	return provider;
       
    56 	} // CWapSmsProvider::NewL
       
    57 
       
    58 
       
    59 /**
       
    60  *  Constructor
       
    61  */
       
    62 CWapSmsProvider::CWapSmsProvider(CWapSmsProtocol* aProtocol)
       
    63     :iMessageType(ESmartMessage)
       
    64     ,iProtocol(aProtocol)
       
    65     ,iSendPending(EFalse)
       
    66 	,iIoctlOutstanding(EFalse)
       
    67 	,iIsNewStyleClient(EFalse)
       
    68 	,iStatusReportScheme(EWapSmsDefault)
       
    69     {
       
    70     iRecvdMsgQueue.SetOffset(CWapDatagram::LinkOffset());
       
    71     } // CWapSmsProvider::CWapSmsProvider
       
    72 
       
    73 
       
    74 /**
       
    75  *  Destructor
       
    76  */
       
    77 CWapSmsProvider::~CWapSmsProvider()
       
    78     {
       
    79     iSAPLink.Deque();
       
    80 
       
    81     while(!iRecvdMsgQueue.IsEmpty())
       
    82         {
       
    83         CWapDatagram* msg = iRecvdMsgQueue.First();
       
    84         iRecvdMsgQueue.Remove(*msg);
       
    85         delete msg;
       
    86         }
       
    87 
       
    88     delete iWapSmsProviderWrite;
       
    89     } // CWapSmsProvider::~CWapSmsProvider
       
    90 
       
    91 
       
    92 /**
       
    93  *  Return WAPSMS options
       
    94  */
       
    95 TInt CWapSmsProvider::GetOption(TUint aLevel,TUint aName, TDes8& aOption)const
       
    96 	{
       
    97 	LOGWAPPROT1("CWapSmsProvider::GetOption");
       
    98 
       
    99 	TInt ret=KErrNone;
       
   100 	if (TInt(aLevel)==KWapSmsOptionLevel && TInt(aName)==KWapSmsOptionNameDCS)
       
   101 		aOption = TPtrC8((TText8*)&iDataCodingScheme,sizeof(TWapSmsDataCodingScheme));
       
   102 	else
       
   103 		ret=iProtocol->GetOption(aLevel,aName,aOption,NULL);
       
   104 	return ret;
       
   105 	} // CWapSmsProvider::GetOption
       
   106 
       
   107 
       
   108 /**
       
   109  *  Set WAPSMS options
       
   110  *  
       
   111  *  @capability None
       
   112  *  
       
   113  */
       
   114 TInt CWapSmsProvider::SetOption(TUint aLevel, TUint aName, const TDesC8& aOption)
       
   115 	{
       
   116 	LOGWAPPROT1("CWapSmsProvider::SetOption");
       
   117 	if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderSetOptionPolicy,"CWapSmsProvider SetOption policy check") != KErrNone))
       
   118 		{
       
   119 		return KErrPermissionDenied;
       
   120 		}
       
   121 
       
   122 	TInt ret=KErrNone;
       
   123 	if (TInt(aLevel)==KWapSmsOptionLevel)
       
   124 	{
       
   125 		switch(TInt(aName))
       
   126 		{
       
   127 		case KWapSmsOptionNameDCS:
       
   128 			{
       
   129 			iDataCodingScheme = static_cast<TWapSmsDataCodingScheme>(*aOption.Ptr());
       
   130 			break;
       
   131 			}
       
   132 		case KWapSmsOptionWapDatagram:
       
   133 			{
       
   134 			iMessageType=EWapDatagram;
       
   135 			break;
       
   136 			}
       
   137 		case KWapSmsStatusReportScheme:
       
   138 			{
       
   139 			iStatusReportScheme = static_cast<TWapSmsStatusReportScheme>(*aOption.Ptr());
       
   140 			break;				
       
   141 			}
       
   142 		case KWapSmsOptionNewStyleClient:
       
   143 			{
       
   144 			iIsNewStyleClient = ETrue;
       
   145 			break;
       
   146 			}
       
   147 		case KWapSmsOptionOKToDeleteMessage:
       
   148 			{
       
   149 			//Get the first message from the queue
       
   150 			CWapDatagram* msg = iRecvdMsgQueue.First();
       
   151 			//Find and delete from SAR
       
   152 			TBool found=iProtocol->FindAndDeleteMsg(*msg);
       
   153 			if(!found)
       
   154 				{
       
   155 				LOGWAPPROT1("CWapSmsProvider::SetOption: Error. Couldn't find the message in the SAR for deletion");
       
   156 				break;
       
   157 				}
       
   158 			//Remove from the queue
       
   159 			iRecvdMsgQueue.Remove(*msg);
       
   160 			delete msg;
       
   161 			break;
       
   162 			}
       
   163 		default:
       
   164 			ret=KErrNotSupported;
       
   165 		}
       
   166 
       
   167 	}
       
   168 	else
       
   169 	{
       
   170 		ret=iProtocol->SetOption(aLevel,aName,aOption,NULL);
       
   171 	}
       
   172 	return ret;
       
   173 	} // CWapSmsProvider::SetOption
       
   174 
       
   175 
       
   176 /**
       
   177  *  Shutdown the SAP
       
   178  */
       
   179 void CWapSmsProvider::Shutdown(TCloseType aType)
       
   180 	{
       
   181 	LOGWAPPROT1("CWapSmsProvider::Shutdown");
       
   182 	if (aType!=CServProviderBase::EImmediate)
       
   183 		iSocket->CanClose();
       
   184 	} // CWapSmsProvider::Shutdown
       
   185 
       
   186 
       
   187 /**
       
   188  *  Setup datagram with socket specific options and forward to protocol
       
   189  *  Return zero to block the send - will be completed by CWapSapMessageSender
       
   190  *  
       
   191  *  @capability NetworkServices
       
   192  */
       
   193 TInt CWapSmsProvider::Write(RMBufChain& aBufChain, TUint /*options*/, TSockAddr* aAddr)
       
   194 	{
       
   195 	LOGWAPPROT1("CWapSmsProvider::Write()");
       
   196 
       
   197 		if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderWritePolicy,"CWapSmsProvider Write policy check") != KErrNone))
       
   198 		{
       
   199 		return KErrPermissionDenied;
       
   200 		}
       
   201 	// @note: LOGIFH2A2 macro for logging esock write
       
   202 #ifdef SMSLOGGERIF
       
   203 	TInt length = aBufChain.Length();
       
   204 	LOGWAPPROT2("CWapSmsProvider::Write [%d bytes]", length);
       
   205 	TBuf8<0x100> dumpBuf;
       
   206 	if(length > 0x100)
       
   207 		{
       
   208 
       
   209 		TInt parts=0;
       
   210 		TInt offset = 0;
       
   211  		while (offset < length)
       
   212  			{
       
   213 			aBufChain.CopyOut(dumpBuf, offset);
       
   214 			offset += length;
       
   215  			LOGIF2(_L8("ESock WAP concantonated part: %d"),parts++);
       
   216  			LOGIF2(_L8("ESOCK WRITE: %S"),&dumpBuf);
       
   217  			LOGIFH2A2(_L8("ESOCK WRITE: "),dumpBuf);
       
   218  			}
       
   219 
       
   220  	}
       
   221  	else
       
   222  	{
       
   223 		aBufChain.CopyOut(dumpBuf, 0);
       
   224  		LOGIF2(_L8("ESOCK WRITE: %S"),&dumpBuf);
       
   225  		LOGIFH2A2(_L8("ESOCK WRITE: "),dumpBuf);
       
   226 	}
       
   227 #endif
       
   228 
       
   229 	// Note that if this fails somehow it still frees the buf chain and sets itself active - it's
       
   230 	// not clear to me whether this is good behaviour but it's the pre-mbuf behaviour too
       
   231 	iWapSmsProviderWrite->Start(aBufChain, *aAddr);
       
   232 	return KErrNone;
       
   233 	} // CWapSmsProvider::Write
       
   234 
       
   235 
       
   236 /**
       
   237  *  Read a datagram off the queue
       
   238  */
       
   239 TInt CWapSmsProvider::GetData(RMBufChain& aBufChain, TUint aLength, TUint /*options*/,TSockAddr* aAddr)
       
   240 	{
       
   241 	LOGWAPPROT1("CWapSmsProvider::GetData()");
       
   242 
       
   243 	CWapDatagram* msg = iRecvdMsgQueue.First();
       
   244 	if(!iIsNewStyleClient)
       
   245 		{
       
   246 		iRecvdMsgQueue.Remove(*msg);
       
   247 		}
       
   248 	TInt err = msg->WapDatagram(aBufChain, aLength);
       
   249 
       
   250 	//@note: LOGIFH2A2 macro for logging esock getdata
       
   251 	LOGWAPPROT1("CWapSmsProvider::GetData");
       
   252 	// Logging migrated to WapDatagram() for ease of descriptor ref
       
   253 
       
   254 	if (err > 0 && aAddr)
       
   255 		{
       
   256 		TWapAddr* wapAddr = reinterpret_cast<TWapAddr*>(aAddr);
       
   257 		TInt toPort,fromPort;
       
   258 		msg->Ports(fromPort,toPort);
       
   259 		wapAddr->SetWapPort(static_cast<TWapPortNumber>(fromPort));
       
   260 		TBuf8<KMaxSockAddrSize> addrBuf;
       
   261 		addrBuf.Copy(msg->FromAddress());
       
   262 		wapAddr->SetWapAddress(addrBuf);
       
   263 		}
       
   264 	if(!iIsNewStyleClient)
       
   265 		{
       
   266 		delete msg;
       
   267 		}
       
   268 	return err > 0? 1: err;		// datagrams are atoms not byte counts
       
   269 	} // CWapSmsProvider::GetData
       
   270 
       
   271 
       
   272 /**
       
   273  *  New data has arrived notify ESOCK.
       
   274  */
       
   275 void CWapSmsProvider::NewData(CWapDatagram* aMsg)
       
   276 	{
       
   277 	TBool notifyEsock = EFalse;
       
   278 	LOGWAPPROT1("CWapSmsProvider::NewData");
       
   279 
       
   280 	if(iIoctlOutstanding && iName==KSOGetLength && iIsNewStyleClient)
       
   281 		{
       
   282 		TPckgBuf<TInt> buf= aMsg->WapDatagramLength();
       
   283 		iSocket->IoctlComplete(&buf);
       
   284 		iIoctlOutstanding= EFalse;
       
   285 		iName= NULL;
       
   286 		notifyEsock = ETrue;
       
   287 		}
       
   288 	else if(iIoctlOutstanding && iName==KSOGetMessageParametersLength && iIsNewStyleClient)
       
   289 		{
       
   290 		CBufFlat* buffer = aMsg->SmsExternalisedStream();
       
   291 		TPckgBuf<TInt> buf = buffer->Size();
       
   292 		iSocket->IoctlComplete(&buf);
       
   293 		iIoctlOutstanding= EFalse;
       
   294 		iName= NULL;
       
   295 		notifyEsock = ETrue;
       
   296 		}
       
   297 	else if(iIoctlOutstanding && iName==KSOGetMessageParameters && iIsNewStyleClient)
       
   298 		{
       
   299 		CBufFlat* buffer = aMsg->SmsExternalisedStream();
       
   300 		TPtr8 buf = buffer->Ptr(0);
       
   301 		iSocket->IoctlComplete(&buf);
       
   302 		iIoctlOutstanding= EFalse;
       
   303 		iName= NULL;
       
   304 		notifyEsock = ETrue;
       
   305 		}
       
   306 	else if(iName!=KSOGetLength && iName!=KSOGetMessageParametersLength && iName!=KSOGetMessageParameters && iIsNewStyleClient)
       
   307 		{
       
   308 		notifyEsock= EFalse;
       
   309 		}
       
   310 
       
   311 	if(!iIsNewStyleClient || notifyEsock)
       
   312 		iSocket->NewData(1);
       
   313 	//else we notify ESock in IOCTL for new client
       
   314 	} // CWapSmsProvider::NewData
       
   315 
       
   316 
       
   317 /**
       
   318  *  Error happened, notify ESOCK
       
   319  */
       
   320 void CWapSmsProvider::Error(TInt aError, TUint aOperationMask)
       
   321 	{
       
   322 	LOGWAPPROT3("CWapSmsProvider::Error [aError=%d, mask=%d] ", aError, aOperationMask);
       
   323 
       
   324 	iSocket->Error(aError, aOperationMask);
       
   325 	} // CWapSmsProvider::Error
       
   326 
       
   327 
       
   328 /**
       
   329  *  Return the offset to the dblquelink
       
   330  */
       
   331 TInt CWapSmsProvider::LinkOffset()
       
   332 	{
       
   333 	LOGWAPPROT1("CWapSmsProvider::LinkOffset");
       
   334 
       
   335 	return _FOFF(CWapSmsProvider,iSAPLink);
       
   336 	} // CWapSmsProvider::LinkOffset
       
   337 
       
   338 
       
   339 /**
       
   340  *  Return the address associated with the sap
       
   341  */
       
   342 void CWapSmsProvider::LocalName(TSockAddr& aAddr) const
       
   343 	{
       
   344 	LOGWAPPROT1("CWapSmsProvider::LocalName");
       
   345 
       
   346 	Mem::Copy(&aAddr,&iLocalAddress,sizeof(TSockAddr));
       
   347 	} // CWapSmsProvider::LocalName
       
   348 
       
   349 
       
   350 /**
       
   351  *  Set the local address of the sap - called by RSocket::Bind
       
   352  *  
       
   353  *  @capability NetworkServices
       
   354  */
       
   355 TInt CWapSmsProvider::SetLocalName(TSockAddr& aAddr)
       
   356 	{
       
   357 	LOGWAPPROT1("CWapSmsProvider::SetLocalName()");
       
   358 
       
   359 		if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderSetLocalNamePolicy,"CWapSmsProvider SetLocalName policy check") != KErrNone))
       
   360 		{
       
   361 		return KErrPermissionDenied;
       
   362 		}
       
   363 	TWapAddr* wapAddr = reinterpret_cast<TWapAddr*>(&aAddr);
       
   364 	LOGWAPPROT2("CWapSmsProvider::SetLocalName %d",wapAddr->WapPort());
       
   365 	// Due ESOCK interface port EWapPortUnspecified value (-1)  can be transferred as a maximum unsigned 16 int
       
   366 	if (wapAddr->WapPort()==EWapPortUnspecified || wapAddr->WapPort()==static_cast<TUint16>(EWapPortUnspecified))
       
   367 		{
       
   368 		if(!iProtocol->AllocateLocalAddress(iLocalAddress))
       
   369 			return KErrInUse;
       
   370 		else return KErrNone;
       
   371 		}
       
   372 
       
   373 
       
   374 	TInt ret=iProtocol->AddrAlreadyUsedByWAP(*wapAddr,this);
       
   375 	if(ret == KErrInUse) return ret;
       
   376 	else if(ret == KErrAlreadyExists) return KErrNone;
       
   377 
       
   378 	TSmsAddr addr;
       
   379 	if(wapAddr->Port() <=255)
       
   380 		addr.SetSmsAddrFamily(ESmsAddrApplication8BitPort);
       
   381 	else
       
   382 		addr.SetSmsAddrFamily(ESmsAddrApplication16BitPort);
       
   383 
       
   384 	addr.SetPort(wapAddr->Port());
       
   385 
       
   386 	if((iProtocol->SmsProtocol()->SmsAddrIsAlreadyUsed(NULL,addr)))
       
   387 		return KErrInUse;
       
   388 
       
   389 	Mem::Copy(&iLocalAddress,&aAddr,sizeof(TSockAddr));
       
   390 	TInt err;
       
   391 	TRAP(err,ret = iProtocol->CheckSarL(*wapAddr,this));
       
   392 	if(err!=KErrNone)
       
   393 			return err;
       
   394 	if(ret!=KErrNone)
       
   395 		{
       
   396 		Error(ret,MSocketNotify::EErrorAllOperations);
       
   397 		}
       
   398 	return KErrNone;
       
   399 	} // RSocket::Bind
       
   400 
       
   401 
       
   402 /**
       
   403  *  Returns true if aAddr matches the local address of the sap
       
   404  */
       
   405 TBool CWapSmsProvider::MatchesLocalAddress(const TWapAddr& aAddr)
       
   406 	{
       
   407 	LOGWAPPROT1("CWapSmsProvider::MatchesLocalAddress");
       
   408 
       
   409 	return (iLocalAddress == aAddr);
       
   410 	} // CWapSmsProvider::MatchesLocalAddress
       
   411 
       
   412 //
       
   413 
       
   414 
       
   415 /**
       
   416  *  Called to perform specific IO control by the client (i.e. Wap Messaging API).The client is able
       
   417  *  to get the size of the datagram once it has been received or confirm the receipt
       
   418  *  of the message.
       
   419  *  
       
   420  *  Only one ioctl request may be outstanding at any one time.
       
   421  *  
       
   422  *  Implementation of pure virtual CServProviderBase::Ioctl().
       
   423  *  
       
   424  *  @param aLevel the IOCTL level. // Can be only KSolWapProv
       
   425  *  @param aName the IOCTL name.
       
   426  *  @param aOption the IOCTL option.
       
   427  *  
       
   428  */
       
   429 void CWapSmsProvider::Ioctl(TUint aLevel,TUint aName,TDes8 * /*aOption*/)
       
   430 	{
       
   431 	LOGWAPPROT3("CWapSmsProvider::Ioctl [aLevel=%d, aName=%d]", aLevel, aName);
       
   432 	LOGWAPPROT2("CWapSmsProtocol::Ioctl [provider=0x%08x]",this);
       
   433 
       
   434 	iName=aName;
       
   435 	switch (aLevel)
       
   436 		{
       
   437 		case KSolWapProv:
       
   438 			{
       
   439 		    if(iIoctlOutstanding || !iIsNewStyleClient)
       
   440 				{
       
   441 				Error(KErrInUse,MSocketNotify::EErrorIoctl);
       
   442 				break;
       
   443 				}
       
   444 			switch (iName)
       
   445 				{
       
   446 				case KSOGetLength:
       
   447 				//
       
   448 				// Get the length
       
   449 				//
       
   450 					{
       
   451 					if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderGetLengthIoctlPolicy,"CWapSmsProvider GetLength Ioctl policy check") != KErrNone))
       
   452         				{
       
   453         				Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
       
   454         				return;
       
   455         				}
       
   456 					iIoctlOutstanding = ETrue;
       
   457 					//check the queue for any other message for this client and call new data if any exist
       
   458 					if(!iRecvdMsgQueue.IsEmpty())
       
   459 						{
       
   460 						CWapDatagram* msg = iRecvdMsgQueue.First();
       
   461 						//check the datagram.
       
   462 						if(msg->IsComplete())
       
   463 							{
       
   464 							NewData(msg);
       
   465 							}
       
   466 						else
       
   467 							{
       
   468 							//	else notify the client with error.
       
   469 							//	Note:this can happen if client uses 8-Bit port number for 7-Bit datagram
       
   470 							Error(KErrGeneral,MSocketNotify::EErrorIoctl);
       
   471 							iIoctlOutstanding = EFalse;
       
   472 							}
       
   473 
       
   474 						}
       
   475 					break;
       
   476 					}
       
   477 				
       
   478 				case KSOGetMessageParametersLength:
       
   479 				//
       
   480 				// Get the Message Parameters Length
       
   481 				//
       
   482 					{
       
   483 					if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderGetMessageParamLengthIoctlPolicy,"CWapSmsProvider KSOGetMessageParametersLength Ioctl policy check") != KErrNone))
       
   484         				{
       
   485         				Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
       
   486         				return;
       
   487         				}
       
   488 					iIoctlOutstanding = ETrue;
       
   489 					//check the queue for any other message for this client and call new data if any exist
       
   490 					if(!iRecvdMsgQueue.IsEmpty())
       
   491 						{
       
   492 						CWapDatagram* msg = iRecvdMsgQueue.First();
       
   493 						//check the datagram.
       
   494 						if(msg->IsComplete())
       
   495 							{
       
   496 							NewData(msg);
       
   497 							}
       
   498 						else
       
   499 							{
       
   500 							//	else notify the client with error.
       
   501 							//	Note:this can happen if client uses 8-Bit port number for 7-Bit datagram
       
   502 							Error(KErrGeneral,MSocketNotify::EErrorIoctl);
       
   503 							iIoctlOutstanding = EFalse;
       
   504 							}
       
   505 
       
   506 						}
       
   507 					break;
       
   508 					}
       
   509 					
       
   510 				case KSOGetMessageParameters:
       
   511 				//
       
   512 				// Get the Message Parameters
       
   513 				//
       
   514 					{
       
   515 					if(!iSecurityChecker || (iSecurityChecker->CheckPolicy(wapSmsProviderGetMessageParametersIoctlPolicy,"CWapSmsProvider GetMessageParameters Ioctl policy check") != KErrNone))
       
   516         				{
       
   517         				Error(KErrPermissionDenied,MSocketNotify::EErrorIoctl);
       
   518         				return;
       
   519         				}
       
   520 					iIoctlOutstanding = ETrue;
       
   521 					//check the queue for any other message for this client and call new data if any exist
       
   522 					if(!iRecvdMsgQueue.IsEmpty())
       
   523 						{
       
   524 						CWapDatagram* msg = iRecvdMsgQueue.First();
       
   525 						//check the datagram.
       
   526 						if(msg->IsComplete())
       
   527 							{
       
   528 							NewData(msg);
       
   529 							}
       
   530 						else
       
   531 							{
       
   532 							//	else notify the client with error.
       
   533 							//	Note:this can happen if client uses 8-Bit port number for 7-Bit datagram
       
   534 							Error(KErrGeneral,MSocketNotify::EErrorIoctl);
       
   535 							iIoctlOutstanding = EFalse;
       
   536 							}
       
   537 
       
   538 						}
       
   539 					break;
       
   540 					}
       
   541 
       
   542 
       
   543 				default:
       
   544 				//
       
   545 				// Unsupported ioctl name
       
   546 				//
       
   547 					{
       
   548 					// Error gracefully
       
   549 					Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
       
   550 					}
       
   551 				}
       
   552 			break;
       
   553 			}
       
   554 		default:
       
   555 			// Gracefully error in release build
       
   556 			Error(KErrNotSupported,MSocketNotify::EErrorIoctl);
       
   557 		}
       
   558 	} // CServProviderBase::Ioctl
       
   559 
       
   560 
       
   561 /**
       
   562  *  Cancel IOCTL- can only have one outstanding IOCTL at a time
       
   563  */
       
   564 void CWapSmsProvider::CancelIoctl(TUint aLevel,TUint aName)
       
   565 	{
       
   566 	LOGWAPPROT1("CWapSmsProvider::CancelIoctl()");
       
   567 
       
   568 	if(!iIoctlOutstanding || (aName!=iName) || (aLevel!=KSolWapProv))
       
   569 		{
       
   570 		Error(KErrNotFound,MSocketNotify::EErrorIoctl);
       
   571 		}
       
   572 	else
       
   573 		{
       
   574 		iIoctlOutstanding=EFalse;
       
   575 		}
       
   576 	} // CWapSmsProvider::CancelIoctl
       
   577 
       
   578 
       
   579 /**
       
   580  *  Start the provider- does nothing
       
   581  */
       
   582 void CWapSmsProvider::Start()
       
   583 	{
       
   584 	LOGWAPPROT1("CWapSmsProvider::Start()");
       
   585 
       
   586 	} // CWapSmsProvider::Start
       
   587 
       
   588 void CWapSmsProvider::AddToQueue(CWapDatagram* aMsg)
       
   589 /**
       
   590  *  Adding the datagram to received messages queue
       
   591  */
       
   592 	{
       
   593 	LOGWAPPROT1("CWapSmsProvider::AddToQueue...");
       
   594 
       
   595 	iRecvdMsgQueue.AddLast(*aMsg);
       
   596 	NewData(aMsg);
       
   597 	} // CWapSmsProvider::AddToQueue
       
   598 
       
   599 
       
   600 TInt CWapSmsProvider::SecurityCheck(MProvdSecurityChecker* aSecurityChecker)
       
   601  	{
       
   602  	LOGWAPPROT1("CWapSmsProvider::SecurityCheck()");
       
   603 
       
   604  	iSecurityChecker=aSecurityChecker;
       
   605 	return KErrNone;
       
   606  	} // CWapSmsProvider::SecurityCheck
       
   607 
       
   608 
       
   609 TWapSmsStatusReportScheme CWapSmsProvider::GetStatusReportScheme()
       
   610 	{
       
   611 	return iStatusReportScheme;
       
   612 	}
       
   613 
       
   614 	
       
   615 TWapSmsDataCodingScheme CWapSmsProvider::GetDataCodingScheme()
       
   616 	{
       
   617 	return iDataCodingScheme;
       
   618 	}
       
   619 
       
   620 
       
   621 //
       
   622 // implementation of CWapSmsProviderWrite
       
   623 //
       
   624 
       
   625 
       
   626 /**
       
   627  *  2 phase constructor
       
   628  */
       
   629 CWapSmsProviderWrite* CWapSmsProviderWrite::NewL(CWapSmsProvider& aWapSmsProvider)
       
   630 	{
       
   631 	LOGWAPPROT1("CWapSmsProviderWrite::NewL");
       
   632 	CWapSmsProviderWrite* self = new (ELeave) CWapSmsProviderWrite(aWapSmsProvider);
       
   633 	CleanupStack::PushL(self);
       
   634 	self->iMsgSender = CWapSapMessageSender::NewL(aWapSmsProvider.iProtocol->SmsProtocol(), &aWapSmsProvider);
       
   635 	CleanupStack::Pop(self);
       
   636 	return self;
       
   637 	} // CWapSmsProviderWrite::NewL
       
   638 
       
   639 
       
   640 /**
       
   641  *  Constructor
       
   642  */
       
   643 CWapSmsProviderWrite::CWapSmsProviderWrite(CWapSmsProvider& aWapSmsProvider)
       
   644     :CActive(EPriorityStandard)
       
   645     ,iWapSmsProvider(aWapSmsProvider)
       
   646     {
       
   647     LOGWAPPROT1("CWapSmsProviderWrite::CWapSmsProviderWrite()");
       
   648 
       
   649     CActiveScheduler::Add(this);
       
   650     } // CWapSmsProviderWrite::CWapSmsProviderWrite
       
   651 
       
   652 
       
   653 /**
       
   654  *  Destructor
       
   655  */
       
   656 CWapSmsProviderWrite::~CWapSmsProviderWrite()
       
   657     {
       
   658     Cancel();
       
   659     delete iMsgSender;
       
   660     delete iDes;
       
   661     } // CWapSmsProviderWrite::~CWapSmsProviderWrite
       
   662 
       
   663 
       
   664 void CWapSmsProviderWrite::Start(RMBufChain& aBufChain, TSockAddr& aAddr)
       
   665    	{
       
   666    	LOGWAPPROT1("CWapSmsProviderWrite::Start");
       
   667    	iWapAddr = reinterpret_cast<TWapAddr&>(aAddr);
       
   668    	delete iDes;
       
   669    	iDes = NULL;
       
   670  	TRAPD(err, (iDes = HBufC8::NewL(aBufChain.Length())) );
       
   671  	if(err == KErrNone)
       
   672  		{
       
   673  		TPtr8 desBuf(iDes->Des());
       
   674  		desBuf.SetLength(aBufChain.Length());
       
   675  		aBufChain.CopyOut(desBuf, 0);
       
   676  		// Logging migrated from CWapSmsProvider::GetData
       
   677  		LOGSMSIF2("ESOCK READ: \"%S\"", iDes);
       
   678  		LOGSMSIFHEXBUF(_L8("ESOCK READ"), *iDes);
       
   679  		LOGSMSIFTIMESTAMP();
       
   680  		}
       
   681  	aBufChain.Free();
       
   682 
       
   683    	TRequestStatus* status = &iStatus;
       
   684    	User::RequestComplete(status, err);
       
   685    	SetActive();
       
   686    	} // CWapSmsProviderWrite::Start
       
   687 
       
   688 
       
   689 void CWapSmsProviderWrite::RunL()
       
   690 	{
       
   691 	LOGWAPPROT1("CWapSmsProviderWrite::RunL");
       
   692 	User::LeaveIfError(iStatus.Int());
       
   693 
       
   694 	//no need to use cleanup stack
       
   695 	CWapDatagram* datagram = CWapDatagram::NewL(*iDes);
       
   696 
       
   697 	if (iWapSmsProvider.iDataCodingScheme == EWapSms7BitDCS)
       
   698 		datagram->SetAlphabet(TSmsDataCodingScheme::ESmsAlphabet7Bit);
       
   699 	else
       
   700 		datagram->SetAlphabet(TSmsDataCodingScheme::ESmsAlphabet8Bit);
       
   701 	
       
   702 	if (iWapSmsProvider.iStatusReportScheme == EWapSmsTPSRR)
       
   703 		{
       
   704 		datagram->SetStatusReportScheme(ETPSRRScheme);
       
   705 		}
       
   706 	else
       
   707 		{
       
   708 		datagram->SetStatusReportScheme(EDefaultScheme);
       
   709 		} 
       
   710 		
       
   711 	TBuf<KMaxSockAddrSize> addrBuf;
       
   712 	addrBuf.Copy(iWapAddr.WapAddress());
       
   713 	datagram->SetToAddress(addrBuf);
       
   714 	TInt fromPort = iWapSmsProvider.iLocalAddress.WapPort();
       
   715 	datagram->SetPorts(fromPort, iWapAddr.WapPort());
       
   716 
       
   717 	iMsgSender->SendDatagramL(datagram); // takes ownership of datagram
       
   718 	} // CWapSmsProviderWrite::RunL
       
   719 
       
   720 
       
   721 TInt CWapSmsProviderWrite::RunError(TInt aError)
       
   722 	{
       
   723 	LOGWAPPROT1("CWapSmsProviderWrite::RunError");
       
   724 	iWapSmsProvider.Error(aError, MSocketNotify::EErrorSend);
       
   725 	return KErrNone;
       
   726 	} // CWapSmsProviderWrite::RunError
       
   727 
       
   728 
       
   729 void CWapSmsProviderWrite::DoCancel()
       
   730 	{
       
   731 	LOGWAPPROT1("CWapSmsProviderWrite::DoCancel");
       
   732 	TRequestStatus* status = &iStatus;
       
   733 	User::RequestComplete(status, KErrCancel);
       
   734 	} // CWapSmsProviderWrite::DoCancel
       
   735 
       
   736 
       
   737 // EOF - WS_PRVDR.CPP