telephonyserverplugins/multimodetsy/Multimode/sms/mSMSSEND.CPP
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     1 // Copyright (c) 1997-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 // Implementation of CATSmsMessagingSend.
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20 */
       
    21 
       
    22 
       
    23 #include <etelmm.h>
       
    24 
       
    25 #include "NOTIFY.H"
       
    26 #include "mSMSMESS.H"
       
    27 #include "mSMSSEND.H"
       
    28 #include "mSLOGGER.H"
       
    29 #include "ATIO.H"
       
    30 #include "smsutil.h"	// for CATSmsUtils
       
    31 
       
    32 //
       
    33 // Constants
       
    34 //
       
    35 const TInt KPduMode=0;
       
    36 
       
    37 //
       
    38 // Macros
       
    39 //
       
    40 
       
    41 #ifdef __LOGDEB__
       
    42 _LIT8(KLogEntry,"CATSmsMessagingSend::%S\t%S");
       
    43 #define LOCAL_LOGTEXT(function,text) {_LIT8(F,function);_LIT8(T,text);LOGTEXT3(KLogEntry,&F,&T);}
       
    44 #else
       
    45 #define LOCAL_LOGTEXT(function,text)
       
    46 #endif
       
    47 
       
    48 /**
       
    49  * CANCEL_AND_RETURN_IF_NEEDED
       
    50  * Used to implement cancellation at safe points inside CATSmsMessagingSend::EventSignal
       
    51  */
       
    52 #define CANCEL_AND_RETURN_IF_NEEDED()\
       
    53 {\
       
    54 if(iStop)\
       
    55 	{\
       
    56 	Complete(KErrCancel);\
       
    57 	LOCAL_LOGTEXT("CANCEL_AND_RETURN_IF_NEEDED","Cancelled");\
       
    58 	return;\
       
    59 	}\
       
    60 }
       
    61 
       
    62 
       
    63 //
       
    64 // Class Implementation
       
    65 //
       
    66 CATSmsMessagingSend* CATSmsMessagingSend::NewL(	CATIO* aIo,
       
    67 												CTelObject* aTelObject,
       
    68 												CATInit* aInit,
       
    69 												CPhoneGlobals* aGsmStatus)
       
    70 /**
       
    71  * Creates a new instance of CATSmsMessagingSend
       
    72  */
       
    73 	{
       
    74 	CATSmsMessagingSend* self=new(ELeave) CATSmsMessagingSend(aIo,aTelObject,aInit,aGsmStatus);
       
    75 	CleanupStack::PushL(self);
       
    76 	self->ConstructL();
       
    77 	CleanupStack::Pop();
       
    78 	return self;
       
    79 	}
       
    80 
       
    81 CATSmsMessagingSend::CATSmsMessagingSend(	CATIO* aIo,
       
    82 											CTelObject* aTelObject,
       
    83 											CATInit* aInit,
       
    84 											CPhoneGlobals* aGsmStatus)
       
    85 	:CATSmsCommands(aIo,aTelObject,aInit,aGsmStatus)
       
    86 /**
       
    87  * C++ constructor
       
    88  */
       
    89 {}
       
    90 
       
    91 void CATSmsMessagingSend::ConstructL()
       
    92 /**
       
    93  * 2nd phase contructor
       
    94  */
       
    95 	{
       
    96 	CATCommands::ConstructL();
       
    97 	iMsgDataAscii.Zero();			// Just in case
       
    98 	}
       
    99 
       
   100 CATSmsMessagingSend::~CATSmsMessagingSend()
       
   101 /**
       
   102  * C++ destructor
       
   103  */
       
   104 	{
       
   105 	delete iMsgData;
       
   106 	}
       
   107 
       
   108 void CATSmsMessagingSend::Start(TTsyReqHandle aTsyReqHandle,TAny* aParams)
       
   109 /**
       
   110  * Starts the procedure of sending an SMS
       
   111  * @param aTsyReqHandle Handle to client, to be completed when operation done
       
   112  * @param aParams Pointer to the SMS PDU (with or without SC prefixed) to be sent 
       
   113  */
       
   114 	{
       
   115 	LOCAL_LOGTEXT("Start","Have been requested to send a message");
       
   116 	
       
   117 	// Intialize data 
       
   118 	iHaveRetriedWithOtherPduStd=EFalse;
       
   119 	iStop=EFalse;
       
   120 
       
   121 	// ::SetMsgAttributes must be called before ::Start is called
       
   122 	__ASSERT_DEBUG(iMsgAttributes,Panic(EATSmsMessagingSendNullMsgAttributes));		
       
   123 
       
   124 	// Save access to the data we be given thru our parameters
       
   125 	iReqHandle=aTsyReqHandle;
       
   126 	delete iMsgData;		// Ensure we don't orphan some memory
       
   127 	iMsgData=((TDesC8*)aParams)->Alloc();
       
   128 	if(!iMsgData)
       
   129 		Complete(KErrNoMemory);
       
   130 
       
   131 	// Kick off first AT stuff
       
   132 	LOCAL_LOGTEXT("Start","Setting phone to PDU mode (as opposed to text mode)");
       
   133 	iTxBuffer.Format(KSmsFormatCommand,KPduMode);
       
   134 	WriteTxBufferToPhone(ESetPhoneToPDUMode);
       
   135 	}
       
   136 
       
   137 
       
   138 void CATSmsMessagingSend::StartFindSCA()
       
   139 /**
       
   140  * Attempt to find an SCA to use when sending message.
       
   141  * The following SCA sources are checked in this order...
       
   142  *    Supplied by client in iMsgAttributes.iSc
       
   143  *    Use default SCA in the phone's memory
       
   144  *	  Use default SCA in the phone's memory after doing 'AT+CRES=1'
       
   145  */
       
   146 	{
       
   147 	LOCAL_LOGTEXT("StartFindSCA","");
       
   148 
       
   149 	// Did client supply SCA in iMsgAttributes.iSc
       
   150 	if(iMsgAttributes->iFlags&RMobileSmsMessaging::KGsmServiceCentre && iMsgAttributes->iGsmServiceCentre.iTelNumber.Length()!=0)
       
   151 		{
       
   152 		iMsgSCA=iMsgAttributes->iGsmServiceCentre;
       
   153 		DoneFindSCA();
       
   154 		}
       
   155 
       
   156 	// Does the phone have a default SCA in memory
       
   157 	else
       
   158 		{
       
   159 		TInt ret=CATSmsCommands::RequestATCommand(CATSmsCommands::EGetSCAFromPhone);
       
   160 		if(ret!=KErrNone)
       
   161 			Complete(ret);
       
   162 		}
       
   163 	
       
   164 	}
       
   165 
       
   166 
       
   167 void CATSmsMessagingSend::DoneFindSCA()
       
   168 	{
       
   169 	LOCAL_LOGTEXT("DoneFindSCA","");
       
   170 	// At this point in the execution we can guarantee that...
       
   171 	//	iMsgData holds the PDU to be sent in binary format without a prepended SCA
       
   172 	//	iMsgSCA holds the SCA to be used to send the PDU
       
   173 
       
   174 	// Check we can handle the Type-Of-Address of the SCA
       
   175 	if(!(iMsgSCA.iNumberPlan==RMobilePhone::EIsdnNumberPlan &&
       
   176 	   (iMsgSCA.iTypeOfNumber==RMobilePhone::EInternationalNumber ||
       
   177 		iMsgSCA.iTypeOfNumber==RMobilePhone::EUnknownNumber)))
       
   178 		{
       
   179 		LOCAL_LOGTEXT("DoneFindSCA","SCA type unsupported");
       
   180 		Complete(KErrCorrupt);
       
   181 		return;
       
   182 		}
       
   183 
       
   184 	// Check which ETSI standard we think phone conforms to
       
   185 	if(PhoneUsesNewPDUStandard())
       
   186 		SendMessageToNewPhone();
       
   187 	else
       
   188 		SendMessageToOldPhone();
       
   189 	}
       
   190 
       
   191 
       
   192 void CATSmsMessagingSend::SendMessageToOldPhone()
       
   193 /**
       
   194  * Send message to phone which uses new ETSI standard (no SCA prefixed to PDU expected,
       
   195  * use phone's default SCA setting instead).
       
   196  */
       
   197  	{
       
   198 	LOCAL_LOGTEXT("SendMessageToOldPhone","");
       
   199 	// Set the SCA to use as the default in the phone's memory
       
   200 	iRequestSCA=iMsgSCA;
       
   201 	TInt ret=CATSmsCommands::RequestATCommand(CATSmsCommands::ESetSCAInPhone);
       
   202 	if(ret!=KErrNone)
       
   203 		Complete(ret);
       
   204 	}
       
   205 
       
   206 
       
   207 void CATSmsMessagingSend::SendMessageToOldPhone_Stage2()
       
   208 	{
       
   209 	// Convert PDU from binary to ASCII
       
   210 	iMsgDataAscii.Zero();
       
   211 	CATSmsUtils::AppendDataToAscii(iMsgDataAscii,*iMsgData);
       
   212 	if(iMsgDataAscii.Length()==0)
       
   213 		{
       
   214 		LOCAL_LOGTEXT("SendMessageToOldPhone_Stage2","Failed to convert binary PDU to ASCII");
       
   215 		Complete(KErrCorrupt);
       
   216 		return;
       
   217 		}
       
   218 
       
   219 	// Send PDU length to the phone
       
   220 	const TInt pduLengthSemiOctets(iMsgDataAscii.Length());
       
   221 	const TInt pduLengthOctets(pduLengthSemiOctets/2+pduLengthSemiOctets%2);
       
   222 	iTxBuffer.Format(KSmsSendPduLengthCommand,pduLengthOctets);
       
   223 	WriteTxBufferToPhone(ESendPDULengthToPhone);
       
   224 	}
       
   225 
       
   226 void CATSmsMessagingSend::SendPDUToPhone()
       
   227 	{
       
   228 	LOCAL_LOGTEXT("SendPDUToPhone","");
       
   229 	// Send PDU to phone 
       
   230 	iTxBuffer.Format(iMsgDataAscii);
       
   231 	iTxBuffer.Append(KCtrlZChar);
       
   232 	WriteTxBufferToPhone(ESendPDUToPhone);
       
   233 	}
       
   234 
       
   235 void CATSmsMessagingSend::SendPDUToPhone_Stage2()
       
   236 	{
       
   237 	// Get the message reference number & submit report and then we've finished 
       
   238 	Complete(ParseCMGSResponse());
       
   239 	}
       
   240 
       
   241 void CATSmsMessagingSend::SendMessageToNewPhone()
       
   242 /**
       
   243  * Send message to phone which uses new ETSI standard (SCA prefixed to PDU expected).
       
   244  */
       
   245 	{
       
   246 	LOCAL_LOGTEXT("SendMessageToNewPhone","");
       
   247 
       
   248 	// Convert SCA to ASCII (ensure that 03.40 format is used to create SCA)
       
   249 	iMsgDataAscii.Zero();
       
   250 	if(CATSmsUtils::AppendAddressToAscii(iMsgDataAscii,iMsgSCA,ETrue)!=KErrNone || iMsgDataAscii.Length()==0)
       
   251 		{
       
   252 		LOCAL_LOGTEXT("SendMessageToNewPhone","Failed to prepend SCA to PDU");
       
   253 		Complete(KErrCorrupt);
       
   254 		return;
       
   255 		}
       
   256 	
       
   257 	// Convert PDU to ASCII
       
   258 	const TInt msgDataAsciiLen(iMsgDataAscii.Length());
       
   259 	CATSmsUtils::AppendDataToAscii(iMsgDataAscii,*iMsgData);
       
   260 	if(iMsgDataAscii.Length()==msgDataAsciiLen)
       
   261 		{
       
   262 		LOCAL_LOGTEXT("SendMessageToNewPhone","Failed to convert binary PDU to ASCII");
       
   263 		Complete(KErrCorrupt);
       
   264 		return;
       
   265 		}
       
   266 
       
   267 	// Send PDU length to the phone
       
   268 	const TInt pduLengthSemiOctets(iMsgDataAscii.Length()-msgDataAsciiLen);	// Must not include the prefixed SCA in calculation
       
   269 	const TInt pduLengthOctets(pduLengthSemiOctets/2+pduLengthSemiOctets%2);
       
   270 	iTxBuffer.Format(KSmsSendPduLengthCommand,pduLengthOctets);
       
   271 	WriteTxBufferToPhone(ESendPDULengthToPhone);
       
   272 	}
       
   273 
       
   274 
       
   275 void CATSmsMessagingSend::EventSignal(TEventSource aSource)
       
   276 /**
       
   277  * Handle the events from the comm port
       
   278  *
       
   279  * This code is first called after the phone has been set to PDU mode.
       
   280  * First we find the SCA that we are going to use. 
       
   281  * Secondly we send the message to the phone depending on whether the phone seems to be using 
       
   282  * the new ETSI format (SCA prefixed to PDU expected) or the old ETSI format (no SCA prefixed
       
   283  * to PDU expected).
       
   284  *
       
   285  * @param aSource denotes if event is due to read, write or timeout
       
   286  */
       
   287 	{
       
   288 	LOCAL_LOGTEXT("EventSignal","");
       
   289 	LOGTEXT3(_L8("iState=%D iSource=%D"),iState,aSource);
       
   290 	LOGTEXT2(_L8("iStop=%D"),iStop);
       
   291 
       
   292 	// Check to see if this class or our base class need to process the event
       
   293 	if(CATSmsCommands::RequestATActive())
       
   294 		{
       
   295 		//
       
   296 		// Allow base class to handle event, and find out if a request completed
       
   297 		//
       
   298 		CATSmsCommands::EventSignal(aSource);
       
   299 		const CATSmsCommands::TRequest reqCompleted(CATSmsCommands::RequestATCompleted());
       
   300 
       
   301 		if(reqCompleted!=ENone)
       
   302 			CANCEL_AND_RETURN_IF_NEEDED();
       
   303 
       
   304 		// Otheriwse, Check if a request completed as a result of the event processing
       
   305 		switch(reqCompleted)
       
   306 			{
       
   307 		case CATSmsCommands::EGetSCAFromPhone:
       
   308 			LOCAL_LOGTEXT("EventSignal","EGetSCAFromPhone completed");
       
   309 			if(iRequestError==KErrNone)
       
   310 				{
       
   311 				iMsgSCA=iRequestSCA;
       
   312 				DoneFindSCA();
       
   313 				}
       
   314 			else
       
   315 				{
       
   316 				LOCAL_LOGTEXT("EventSignal","Failed to find an SCA to use");
       
   317 				Complete(iRequestError,aSource);
       
   318 				}
       
   319 			break;
       
   320 
       
   321 		case CATSmsCommands::ESetSCAInPhone:
       
   322 			LOCAL_LOGTEXT("EventSignal","ESetSCAInPhone completed");
       
   323 			if(iRequestError==KErrNone)
       
   324 				SendMessageToOldPhone_Stage2();
       
   325 			else
       
   326 				{
       
   327 				LOCAL_LOGTEXT("EventSignal","Failed to set SCA in phone");
       
   328 				Complete(iRequestError,aSource);
       
   329 				}
       
   330 			break;
       
   331 
       
   332 		case CATSmsCommands::ENone:	// Must not be caught by default case 
       
   333 			break;
       
   334 		default:
       
   335 			LOCAL_LOGTEXT("EventSignal","CATSmsCommands unknown request completed");
       
   336 			__ASSERT_DEBUG(EFalse,Panic(EATSmsMessagingUnknownRequestCompleted));
       
   337 			}
       
   338 		}
       
   339 	else
       
   340 		{
       
   341 		//
       
   342 		// This class will handle event
       
   343 		//
       
   344 		if (aSource==ETimeOutCompletion)
       
   345 			{
       
   346 			LOCAL_LOGTEXT("EventSignal","Timeout error");
       
   347 			iIo->WriteAndTimerCancel(this);
       
   348 			Complete(KErrTimedOut, aSource);
       
   349 			}
       
   350 
       
   351 		TInt ret(KErrNone);
       
   352 		switch(iState)
       
   353 			{
       
   354 		case ESetPhoneToPDUMode:
       
   355 			if(aSource==EWriteCompletion)
       
   356 				HandleWriteCompletion(aSource);		
       
   357 			else
       
   358 				{
       
   359 				ret=HandleResponseCompletion(aSource,EFalse);
       
   360 				if (ret!=KErrNone)
       
   361 					{
       
   362 					Complete(ret,aSource);
       
   363 					return;
       
   364 					}		
       
   365 				StartFindSCA();
       
   366 				}
       
   367 			break;
       
   368 
       
   369 		case ESendPDULengthToPhone:
       
   370 			if(aSource==EWriteCompletion)
       
   371 				{
       
   372 				HandleWriteCompletion(aSource);
       
   373 				iExpectString=iIo->AddExpectString(this,KSmsEnterPduModeResponse,ETrue);
       
   374 				}
       
   375 			else
       
   376 				{
       
   377 				ret=HandleResponseCompletion(aSource,EFalse);
       
   378 				if (ret!=KErrNone)
       
   379 					{
       
   380 					Complete(ret,aSource);
       
   381 					return;
       
   382 					}		
       
   383 				ret=ConvertCMSErrorToKErr(CMSErrorValue());
       
   384 				iIo->RemoveExpectString(iExpectString);
       
   385 				iExpectString=NULL;
       
   386 				if (ret!=KErrNone)
       
   387 					{
       
   388 					Complete(ret,aSource);
       
   389 					return;
       
   390 					}		
       
   391 
       
   392 				// If we get a Cancel request just before we send the PDU, we instead send an escape 
       
   393 				// character to trigger a PDU send failure and then continue as normal.
       
   394 				if (iStop)
       
   395 					{
       
   396 					LOCAL_LOGTEXT("EventSignal","Cancel requested. Sending Escape Character instead of PDU");
       
   397 					
       
   398 					// In case of Ericsson phone, after sending the escape char we are not receiving expected
       
   399 					// response (OK/ERROR), it is just echoing those char. But if the escape char is prefixed
       
   400 					// by "at", then it responds with expected response.
       
   401 
       
   402 					// But in case of other phones, we believe the escape char alone works.  We have confirmed
       
   403 					// this with Nokia phones.
       
   404 
       
   405 					_LIT16(KEricsson,"*ERICSSON*");
       
   406 					if(iPhoneGlobals->iPhoneId.iManufacturer.MatchF(KEricsson)==0)
       
   407 						{
       
   408 						_LIT8(KEscapeSequenceString,"at%S\r");
       
   409 						iTxBuffer.Format(KEscapeSequenceString,&KEscapeChar);
       
   410 						}
       
   411 					else
       
   412 						{
       
   413 						iTxBuffer.Format(KEscapeChar);
       
   414 						}
       
   415 					WriteTxBufferToPhone(ESendEscapeCharToPhone);
       
   416 					}
       
   417 				else
       
   418 					SendPDUToPhone();
       
   419 				}
       
   420 			break;
       
   421 		
       
   422 		case ESendPDUToPhone:
       
   423 			if(aSource==EWriteCompletion)
       
   424 				{
       
   425 				HandleWriteCompletion(aSource);
       
   426 				}
       
   427 			else
       
   428 				{
       
   429 				const TInt err=ConvertCMSErrorToKErr(CMSErrorValue());
       
   430 				ret=HandleResponseCompletion(aSource,EFalse);
       
   431 				if (ret!=KErrNone)
       
   432 					{
       
   433 					Complete(ret,aSource);
       
   434 					return;
       
   435 					}		
       
   436 
       
   437 				// Check if an error occurred
       
   438 				if(err!=KErrNone)
       
   439 					{
       
   440 					// If we have not already, then retry using the other Pdu standard
       
   441 					if(!iHaveRetriedWithOtherPduStd)
       
   442 						{
       
   443 						CANCEL_AND_RETURN_IF_NEEDED();
       
   444 						// Retry with new standard
       
   445 						LOCAL_LOGTEXT("EventSignal","Failed to send message, will retry using other phone standard");
       
   446 						iHaveRetriedWithOtherPduStd=ETrue;
       
   447 						TogglePhonePDUStandard();
       
   448 						DoneFindSCA();
       
   449 						}
       
   450 					else
       
   451 						{
       
   452 						// We have tried both PDU standards and have failed :-(
       
   453 						LOCAL_LOGTEXT("EventSignal","Failed to send message :-(");
       
   454 						Complete(err,aSource);
       
   455 						}
       
   456 					}
       
   457 				else
       
   458 					{
       
   459 					// Success, we have sent the message ;-)
       
   460 					if (iStop)	{LOCAL_LOGTEXT("EventSignal","Message send successful, Cancel request to late, PDU already sent");}
       
   461 					else		{LOCAL_LOGTEXT("EventSignal","Message send successful ;-)");}
       
   462 					SendPDUToPhone_Stage2();
       
   463 					}
       
   464 				}
       
   465 			break;
       
   466 		
       
   467 		case ESendEscapeCharToPhone:
       
   468 			if(aSource==EWriteCompletion)
       
   469 				{
       
   470 				HandleWriteCompletion(aSource);
       
   471 				}
       
   472 			else
       
   473 				{
       
   474 				ret=HandleResponseCompletion(aSource,EFalse);
       
   475 				if (ret!=KErrNone)
       
   476 					{
       
   477 					Complete(ret,aSource);
       
   478 					return;
       
   479 					}
       
   480 				Complete(KErrCancel,aSource);
       
   481 				}
       
   482 			break;
       
   483 
       
   484 		case ENotInProgress: // Required to stop 'unhandled enum' warning with ARM4
       
   485 			break;
       
   486 			}
       
   487 		}
       
   488 	}
       
   489 
       
   490 
       
   491 void CATSmsMessagingSend::Complete(TInt aError,TEventSource aSource)
       
   492 	{
       
   493 	LOCAL_LOGTEXT("Complete","");
       
   494 	LOGTEXT3(_L8("aError=%D aSource=%D"),aError,aSource);
       
   495 
       
   496 	iIo->WriteAndTimerCancel(this);
       
   497 	iIo->RemoveExpectStrings(this);
       
   498 	iOKExpectString = NULL;
       
   499 	iErrorExpectString = NULL;
       
   500 	CATCommands::Complete(aError,aSource);
       
   501 	iTelObject->ReqCompleted(iReqHandle, aError);
       
   502 	if (aSource==EWriteCompletion)
       
   503 		iIo->Read();
       
   504 	iState = ENotInProgress; 
       
   505 	}
       
   506 
       
   507 void CATSmsMessagingSend::SetMsgAttributes(RMobileSmsMessaging::TMobileSmsSendAttributesV1* aMsgAttributes)
       
   508 	{
       
   509 	iMsgAttributes=aMsgAttributes;
       
   510 	}
       
   511 
       
   512 void CATSmsMessagingSend::Stop(TTsyReqHandle aTsyReqHandle)
       
   513 //
       
   514 //	Attempts to halt the process
       
   515 //
       
   516 	{
       
   517 	LOCAL_LOGTEXT("Stop","Client has requested cancel");
       
   518 	__ASSERT_ALWAYS(aTsyReqHandle == iReqHandle, Panic(EIllegalTsyReqHandle));
       
   519 
       
   520 	// Ensure our base class notes that a cancel has been requested
       
   521 	CATSmsCommands::RequestATCommandCancel();
       
   522 
       
   523 	// Set our flag to denote we should cancel as soon as possible
       
   524 	iStop=ETrue;
       
   525 	}
       
   526 
       
   527 void CATSmsMessagingSend::CompleteWithIOError(TEventSource /*aSource*/,TInt aStatus)
       
   528 	{
       
   529 	if (iState!=ENotInProgress)
       
   530 		{
       
   531 		iIo->WriteAndTimerCancel(this);
       
   532 		iTelObject->ReqCompleted(iReqHandle, aStatus);
       
   533 		iState = ENotInProgress;
       
   534 		}
       
   535 	}
       
   536 
       
   537 //
       
   538 // Utility functions 
       
   539 //
       
   540 TBool CATSmsMessagingSend::PhoneUsesNewPDUStandard()
       
   541 /**
       
   542  * This code assumes that EPhoneTestOldStandard and EPhoneTestUndefined are 
       
   543  * the same.
       
   544  */
       
   545  	{
       
   546 	return (iPhoneGlobals->iPhoneTestState==CPhoneGlobals::EPhoneTestNewStandard);
       
   547 	}
       
   548 
       
   549 void CATSmsMessagingSend::TogglePhonePDUStandard()
       
   550 /**
       
   551  * This code assumes that EPhoneTestOldStandard and EPhoneTestUndefined are 
       
   552  * the same.
       
   553  */
       
   554 	{
       
   555 	if(iPhoneGlobals->iPhoneTestState==CPhoneGlobals::EPhoneTestNewStandard)
       
   556 		iPhoneGlobals->iPhoneTestState=CPhoneGlobals::EPhoneTestOldStandard;		
       
   557 	else
       
   558 		iPhoneGlobals->iPhoneTestState=CPhoneGlobals::EPhoneTestNewStandard;		
       
   559 	}
       
   560 
       
   561 void CATSmsMessagingSend::WriteTxBufferToPhone(TState aNewState)
       
   562 /**
       
   563  * Sends the contents of iTxBuffer to the phone
       
   564  */
       
   565  	{
       
   566 	iIo->Write(this,iTxBuffer);
       
   567 	iIo->SetTimeOut(this,KATWriteTimeout);
       
   568 	iState=aNewState;
       
   569 	}
       
   570 
       
   571 
       
   572 TInt CATSmsMessagingSend::ParseCMGSResponse()		
       
   573 /**
       
   574  * Parse CMGS response string for Message Reference Number &
       
   575  * SUBMIT-REPORT PDU (optional) and store their values in the clients data space.
       
   576  *
       
   577  * @return Standard KErr... values
       
   578  */
       
   579 	{
       
   580 	__ASSERT_DEBUG(iMsgAttributes,Panic(EATSmsMessagingSendNullMsgAttributes));		
       
   581 
       
   582 	iBuffer.Set(iIo->Buffer());
       
   583 	TInt pos=iBuffer.FindF(KCMGSResponseString);
       
   584 	if (pos==KErrNotFound)
       
   585 		{
       
   586 		LOCAL_LOGTEXT("ParseCMGSResponse","Cannot find '+CMGS:' string");
       
   587 		return KErrNotFound;
       
   588 		}
       
   589 	
       
   590 	// Locate the message reference number
       
   591 	// (ie. read in all digits form the first found to the end of the string)
       
   592 	const TInt bufLength=iBuffer.Length();
       
   593 	pos+=KCMGSResponseStringLength;
       
   594 	while(pos<bufLength && !(TChar(iBuffer[pos]).IsDigit()))
       
   595 		++pos;
       
   596 	if(pos>=bufLength)
       
   597 		{
       
   598 		LOCAL_LOGTEXT("ParseCMGSResponse","Cannot find any digits after '+CMGS:'");
       
   599 		return KErrNotFound;
       
   600 		}
       
   601 
       
   602 	// Read message number and store in clients data structure
       
   603 	TPtrC8 ptr=iBuffer.Mid(pos);	
       
   604 	TLex8 lex(ptr);
       
   605 	TUint16 val;
       
   606 	TInt ret=lex.Val(val,EDecimal);
       
   607 	if(ret!=KErrNone)
       
   608 		{
       
   609 		LOCAL_LOGTEXT("ParseCMGSResponse","Unable to read Message Reference Number");
       
   610 		return ret;
       
   611 		}
       
   612 	LOGTEXT2(_L8("CATSmsMessagingSend    Message reference number %d"),val);
       
   613 	iMsgAttributes->iMsgRef=val;
       
   614 	iMsgAttributes->iFlags|=RMobileSmsMessaging::KMessageReference;
       
   615 
       
   616 	// Locate SUBMIT-REPORT (it does not have to exist)
       
   617 	pos=iBuffer.FindF(KCommaChar);
       
   618 	if(pos!=KErrNotFound)
       
   619 		{
       
   620 		while(pos<bufLength && !(TChar(iBuffer[pos]).IsHexDigit()))
       
   621 			++pos;
       
   622 
       
   623 		if(pos<bufLength)
       
   624 			{
       
   625 			// We have found a SUBMIT-REPORT PDU, so save it to clients data space
       
   626 			LOCAL_LOGTEXT("ParseCMGSResponse","Found SUBMIT-REPORT PDU");
       
   627 
       
   628 			iMsgAttributes->iSubmitReport.Zero();
       
   629 			while(pos<bufLength && TChar(iBuffer[pos]).IsHexDigit())
       
   630 				{
       
   631 				iMsgAttributes->iSubmitReport.Append(TChar(iBuffer[pos]));
       
   632 				++pos;
       
   633 				}
       
   634 			iMsgAttributes->iFlags|=RMobileSmsMessaging::KGsmSubmitReport;
       
   635 			}
       
   636 		}
       
   637 
       
   638 	return KErrNone;
       
   639 	}
       
   640 
       
   641