smsprotocols/smsstack/gsmu/src/gsmuieoperations.cpp
changeset 0 3553901f7fa8
child 19 630d2f34d719
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 //
       
    15 
       
    16 #include "Gsmumain.h"
       
    17 #include "gsmuieoperations.h"
       
    18 #include "Gsmumsg.h"
       
    19 #include "gsmumsgadditionalattributes.h"
       
    20 #include "Gsmuelem.h"
       
    21 #include "smsstacklog.h"
       
    22 
       
    23 
       
    24 /**
       
    25  *  This is used by the CSmsMessage to create a CSmsIEOperation.
       
    26  *  Each instance is owned by the CSmsMessage which created it.
       
    27  *  Therefore only the CSmsMessage (GSMU component) is allowed to
       
    28  *  create and delete CSmsIEOperations.
       
    29  *  
       
    30  *  @param aId
       
    31  *  The ID for the CSmsInformationElement for whom an operation class needs to be created.
       
    32  *  @param aMessage
       
    33  *  The CSmsMessage that this operations class belongs to.
       
    34  *  @param aCharacterSetConverter
       
    35  *  A reference to a character set converter, needed by some derived operation classes.
       
    36  *  @param aFs
       
    37  *  A reference to the file server, needed by some derived operations classes.
       
    38  *  
       
    39  *  @internalComponent
       
    40  */
       
    41 CSmsIEOperation*  CSmsIEOperation::NewL(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage, CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs)
       
    42 	{
       
    43 	LOGGSMU1("CSmsIEOperation::NewL()");
       
    44 
       
    45 	CSmsIEOperation* iEOperation = NULL;
       
    46 
       
    47 	switch (aId)
       
    48 	    {
       
    49 	    case CSmsInformationElement::ESmsHyperLinkFormat:
       
    50 	        iEOperation = new (ELeave)  CSmsHyperLinkOperations(aId,aMessage);
       
    51 	        break;
       
    52 	    case CSmsInformationElement::ESmsReplyAddressFormat:
       
    53 	        iEOperation = new (ELeave) CSmsReplyAddressOperations(aId, aMessage, aCharacterSetConverter, aFs);
       
    54 	        break;
       
    55 	    case CSmsInformationElement::ESmsEnhanceVoiceMailInformation:
       
    56 	        iEOperation = new (ELeave) CSmsEnhancedVoiceMailOperations(aId, aMessage, aCharacterSetConverter, aFs);
       
    57 	        break;
       
    58 	    case CSmsInformationElement::ESmsIEISpecialSMSMessageIndication:
       
    59 	        iEOperation = new (ELeave)  CSmsSpecialSMSMessageOperations(aId,aMessage);
       
    60 	        break;
       
    61 	    case CSmsInformationElement::ESmsIEISMSCControlParameters:
       
    62 	        iEOperation = new (ELeave)  CSmsSMSCCtrlParameterOperations(aId,aMessage); 
       
    63 	        break;
       
    64 	    default:
       
    65 	        User::Leave(KErrArgument);
       
    66 	        break;
       
    67 	    }
       
    68 
       
    69 	iEOperation->ConstructL();
       
    70 
       
    71 	return iEOperation;
       
    72 	} // CSmsIEOperation::NewL
       
    73 
       
    74 
       
    75 /**
       
    76  *  @publishedAll
       
    77  *  
       
    78  *  Identifies the information element which is supported by this operations class.
       
    79  *  
       
    80  *  @return The information element ID supported by this operations class.
       
    81  *  @capability None
       
    82  */
       
    83 EXPORT_C CSmsInformationElement::TSmsInformationElementIdentifier CSmsIEOperation::Id() const
       
    84 	{
       
    85 	LOGGSMU1("CSmsIEOperation::Id()");
       
    86 
       
    87 	return iId;
       
    88 	} // CSmsInformationElement::TSmsInformationElementIdentifier
       
    89 
       
    90 
       
    91 /**
       
    92  *  @internalComponent
       
    93  *  
       
    94  *  Identifies whether the message type supports is supported
       
    95  *  
       
    96  *  @return True if the message type is supported. False otherwise.
       
    97  */
       
    98 TBool CSmsIEOperation::MessageTypeSupported() const
       
    99 	{
       
   100 	LOGGSMU1("CSmsIEOperation::MessageTypeSupported()");
       
   101 
       
   102 	CSmsPDU::TSmsPDUType type = iMessage.Type();
       
   103 
       
   104     return ((type == CSmsPDU::ESmsDeliver) ||
       
   105             (type == CSmsPDU::ESmsSubmit));
       
   106 	} // CSmsIEOperation::MessageTypeSupported
       
   107 
       
   108 
       
   109 CSmsIEOperation::CSmsIEOperation(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage) : iId(aId), iMessage(aMessage)
       
   110 	{
       
   111 	//NOP
       
   112 	} // CSmsIEOperation::CSmsIEOperation
       
   113 
       
   114 
       
   115 /**
       
   116  *  @internalComponent
       
   117  *  
       
   118  *  Prevent clients from using the assignment operator by including it in the class definition
       
   119  *  but making it protected and not exporting it.
       
   120  *  
       
   121  *  @capability None
       
   122  */
       
   123 void CSmsIEOperation::operator=(const CSmsIEOperation&)
       
   124     {
       
   125     // Ignore in code coverage - not intended to be used
       
   126     BULLSEYE_OFF    
       
   127     LOGGSMU1("CSmsIEOperation::operator=");
       
   128     Panic(KGsmuPanicMethodBodyNotImplemented1);
       
   129     BULLSEYE_RESTORE
       
   130     }
       
   131 
       
   132 /**
       
   133  *  @internalComponent
       
   134  *  
       
   135  *  Prevent clients from using the equality operator by including it in the class definition
       
   136  *  but making it protected and not exporting it.
       
   137  *  
       
   138  *  @capability None
       
   139  */
       
   140 TBool CSmsIEOperation::operator==(const CSmsIEOperation&)
       
   141     {
       
   142     // Ignore in code coverage - not intended to be used
       
   143     BULLSEYE_OFF    
       
   144     LOGGSMU1("CSmsIEOperation::operator==");
       
   145     Panic(KGsmuPanicMethodBodyNotImplemented1);
       
   146     return EFalse;
       
   147     BULLSEYE_RESTORE
       
   148     }
       
   149 
       
   150 /**
       
   151  *  @internalComponent
       
   152  *  
       
   153  *  Prevent clients from using the assignment operator by including it in the class definition
       
   154  *  but making it protected and not exporting it.
       
   155  *  
       
   156  *  @capability None
       
   157  */
       
   158 void CSmsCtrlOperation::operator=(const CSmsCtrlOperation&)
       
   159     {
       
   160     // Ignore in code coverage - not intended to be used
       
   161     BULLSEYE_OFF    
       
   162     LOGGSMU1("CSmsCtrlOperation::operator=");
       
   163     Panic(KGsmuPanicMethodBodyNotImplemented1);
       
   164     BULLSEYE_RESTORE
       
   165     }
       
   166 
       
   167 /**
       
   168  *  @internalComponent
       
   169  *  
       
   170  *  Prevent clients from using the equality operator by including it in the class definition
       
   171  *  but making it protected and not exporting it.
       
   172  *  
       
   173  *  @capability None
       
   174  */
       
   175 TBool CSmsCtrlOperation::operator==(const CSmsCtrlOperation&)
       
   176     {
       
   177     // Ignore in code coverage - not intended to be used
       
   178     BULLSEYE_OFF    
       
   179     LOGGSMU1("CSmsCtrlOperation::operator==");
       
   180     Panic(KGsmuPanicMethodBodyNotImplemented1);
       
   181     return EFalse;
       
   182     BULLSEYE_RESTORE
       
   183     }
       
   184 
       
   185 CSmsCtrlOperation::CSmsCtrlOperation(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage) : CSmsIEOperation(aId, aMessage)
       
   186 	{
       
   187 	//NOP
       
   188 	} // CSmsCtrlOperation::CSmsCtrlOperation
       
   189 
       
   190 
       
   191 CSmsHyperLinkOperations::CSmsHyperLinkOperations(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage) : CSmsCtrlOperation(aId, aMessage)
       
   192 	{
       
   193 	//NOP
       
   194 	} // CSmsHyperLinkOperations::CSmsHyperLinkOperations
       
   195 
       
   196 
       
   197 void CSmsIEOperation::ConstructL()
       
   198 	{
       
   199 	LOGGSMU1("CSmsIEOperation::ConstructL()");
       
   200 	} // CSmsIEOperation::ConstructL
       
   201 
       
   202 
       
   203 /**
       
   204  *  @internalComponent
       
   205  *  
       
   206  *  Prevent clients from using the assignment operator by including it in the class definition
       
   207  *  but making it protected and not exporting it.
       
   208  *  
       
   209  *  @capability None
       
   210  */
       
   211 void CSmsHyperLinkOperations::operator=(const CSmsHyperLinkOperations&)
       
   212     {
       
   213     // Ignore in code coverage - not intended to be used
       
   214     BULLSEYE_OFF    
       
   215     LOGGSMU1("CSmsHyperLinkOperations::operator=");
       
   216     Panic(KGsmuPanicMethodBodyNotImplemented1);
       
   217     BULLSEYE_RESTORE
       
   218     }
       
   219 
       
   220 /**
       
   221  *  @internalComponent
       
   222  *  
       
   223  *  Prevent clients from using the equality operator by including it in the class definition
       
   224  *  but making it protected and not exporting it.
       
   225  *  
       
   226  *  @capability None
       
   227  */
       
   228 TBool CSmsHyperLinkOperations::operator==(const CSmsHyperLinkOperations&)
       
   229     {
       
   230     // Ignore in code coverage - not intended to be used
       
   231     BULLSEYE_OFF    
       
   232     LOGGSMU1("CSmsHyperLinkOperations::operator==");
       
   233     Panic(KGsmuPanicMethodBodyNotImplemented1);
       
   234     return EFalse;
       
   235     BULLSEYE_RESTORE
       
   236     }
       
   237 
       
   238 /**
       
   239  *  @internalComponent
       
   240  *  
       
   241  *  Identifies whether the message type or version supports this operation
       
   242  *  
       
   243  *  @leave
       
   244  *  If the message type or version does not support this operation.
       
   245  */
       
   246 void CSmsHyperLinkOperations::ValidateOperationL() const
       
   247 	{
       
   248 	LOGGSMU1("CSmsHyperLinkOperations::ValidateOperationL()");
       
   249 
       
   250 	if (iMessage.Version() < CSmsMessage::ESmsMessageV1)
       
   251 	    {
       
   252 	    LOGGSMU2("CSmsHyperLinkOperations::AddHyperLinkL, Operation not supported, Msg Version %d", iMessage.Version());
       
   253 	    User::Leave(KErrNotSupported);
       
   254 	    }
       
   255 
       
   256 	if (!MessageTypeSupported())
       
   257 	    {
       
   258 	    LOGGSMU2("CSmsHyperLinkOperations::AddHyperLinkL, Operation not supported by this PDU type, type = %d", iMessage.Type());
       
   259 	    User::Leave(KErrNotSupported);
       
   260 	    }
       
   261 	} // CSmsHyperLinkOperations::ValidateOperationL
       
   262 
       
   263 
       
   264 /**
       
   265  *  @publishedAll
       
   266  *  
       
   267  *  This method adds a HyperLink to the CSmsMessage.
       
   268  *  
       
   269  *  @param aPosition
       
   270  *  The absolute character position within the message text.
       
   271  *  @param aTitle
       
   272  *  An integer representation of the number of characters in the hyperlink title.
       
   273  *  @param URL Length
       
   274  *  An integer representation of the number of characters in the URL.
       
   275  *  @leave KErrNotSupported
       
   276  *  If the message version or type does not support hyperlinks.
       
   277  *  @capability None
       
   278  */
       
   279 EXPORT_C void CSmsHyperLinkOperations::AddHyperLinkL(TUint aPosition, TUint8 aTitleLength,  TUint8  aURLLength) const
       
   280 	{
       
   281 	LOGGSMU1("CSmsHyperLinkOperations::AddHyperLinkL()");
       
   282 
       
   283 	ValidateOperationL();
       
   284 
       
   285 	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
       
   286 
       
   287 	TBuf8 <4> buffer;
       
   288 	buffer.SetLength(4);
       
   289 	buffer[0] = (TUint8) (aPosition >> 8); // lowest octet contains the
       
   290 	buffer[1] = (TUint8)  aPosition;       // most significant bits
       
   291 	buffer[2] = aTitleLength;
       
   292 	buffer[3] = aURLLength;
       
   293 
       
   294 	CSmsInformationElement* iE = CSmsInformationElement::NewL(CSmsInformationElement::ESmsHyperLinkFormat, buffer);
       
   295 	CleanupStack::PushL(iE);
       
   296 	additionalAttributes.AddControlInformationElementL(iE);
       
   297 	CleanupStack::Pop(iE);
       
   298 	} // CSmsHyperLinkOperations::AddHyperLinkL
       
   299 
       
   300 
       
   301 /**
       
   302  *  @publishedAll
       
   303  *  
       
   304  *  Returns the number of Hyper Link IEs contained in this message.
       
   305  *  @leave KErrNotSupported
       
   306  *  If this functionality is not supported by this version or type of message.
       
   307  *  @return
       
   308  *  The number of hyper links contained in this message.
       
   309  *  @capability None
       
   310  */
       
   311 EXPORT_C TUint CSmsHyperLinkOperations::NumberOfHyperLinksL() const
       
   312 	{
       
   313 	LOGGSMU1("CSmsHyperLinkOperations::NumberOfHyperLinks");
       
   314 
       
   315 	ValidateOperationL();
       
   316 
       
   317 	TUint numberOfHyperLinks = 0;
       
   318 
       
   319 	TSmsInformationElementCategories::TInformationElementCategory category;
       
   320 
       
   321 	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsHyperLinkFormat, category) == EFalse)
       
   322 			{
       
   323 		User::Leave(KErrArgument);
       
   324 		}
       
   325 
       
   326 	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
       
   327 	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
       
   328 
       
   329 	for (TUint i = 0; i < numberOfElements; i++)
       
   330 	    {
       
   331 	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
       
   332 	    
       
   333 	    // If function leaves, allow the error to propagate upwards
       
   334 	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
       
   335 
       
   336 	    if (id == CSmsInformationElement::ESmsHyperLinkFormat)
       
   337 	        {
       
   338 	        numberOfHyperLinks++;
       
   339 	        }
       
   340 	    }
       
   341 
       
   342 	return numberOfHyperLinks;
       
   343 	} // CSmsHyperLinkOperations::NumberOfHyperLinksL
       
   344 
       
   345 
       
   346 /**
       
   347  *  @publishedAll
       
   348  *  
       
   349  *  Copies the attributes of the specified hyperlink.
       
   350  *  aIndex has the range [0..[n-1]] where n is the
       
   351  *  value returned by NumberOfHyperLinks()
       
   352  *  
       
   353  *  @param aIndex
       
   354  *  Identifies the hyperlink to extract. Has the range [0..[n-1]]
       
   355  *  where n is the value returned by NumberOfHyperLinks().
       
   356  *  @param &aPosition
       
   357  *  The absolute character position within the message text.
       
   358  *  @param &aTitleLength
       
   359  *  An integer representation of the number of characters in the hyperlink title.
       
   360  *  @param &aURLLength
       
   361  *  An integer representation of the number of characters in the URL.
       
   362  *  @leave KErrNotSupported
       
   363  *  If the message version or type does not support hyperlinks.
       
   364  *  @leave KErrArgument
       
   365  *  If aIndex is out of range.
       
   366  *  @capability None
       
   367  */
       
   368 EXPORT_C void  CSmsHyperLinkOperations::CopyHyperLinkAtIndexL(TUint aIndex, TUint& aPosition, TUint8& aTitleLength,  TUint8&  aURLLength) const
       
   369 	{
       
   370 	LOGGSMU2("CSmsHyperLinkOperations::CopyHyperLinkAtIndexL(): aIndex=%d", aIndex);
       
   371 
       
   372 	ValidateOperationL();
       
   373 
       
   374 	TUint numberOfHyperLinks = 0;
       
   375 
       
   376 	TSmsInformationElementCategories::TInformationElementCategory category;
       
   377 	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsHyperLinkFormat, category) == EFalse)
       
   378 		{
       
   379 		User::Leave(KErrArgument);
       
   380 		}
       
   381 
       
   382 	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
       
   383 	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
       
   384 
       
   385 	if (aIndex >= numberOfElements)
       
   386 	    {
       
   387 	    User::Leave(KErrArgument);
       
   388 	    }
       
   389 
       
   390 	for (TUint i = 0; i < numberOfElements; i++)
       
   391 	    {
       
   392 	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
       
   393 	    
       
   394 	    // If function leaves, allow the error to propagate upwards
       
   395 	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
       
   396 
       
   397 	    if ((id == CSmsInformationElement::ESmsHyperLinkFormat) &&
       
   398 	        (numberOfHyperLinks++ == aIndex))
       
   399 	        {
       
   400 	        aPosition     = (additionalAttributes->GetControlInformationElementL(category, i).Data()[0] << 8);
       
   401 	        aPosition    +=  additionalAttributes->GetControlInformationElementL(category, i).Data()[1];
       
   402 
       
   403 	        aTitleLength = additionalAttributes->GetControlInformationElementL(category, i).Data()[2];
       
   404 	        aURLLength   = additionalAttributes->GetControlInformationElementL(category, i).Data()[3];
       
   405 	        break;
       
   406 	        }
       
   407 	    }
       
   408 	} // CSmsHyperLinkOperations::CopyHyperLinkAtIndexL
       
   409 
       
   410 
       
   411 /**
       
   412  *  @publishedAll
       
   413  *  
       
   414  *  Removes all hyper Link IEs contained in this message.
       
   415  *  
       
   416  *  @leave KErrNotSupported
       
   417  *  If the message version or type does not support hyperlinks.
       
   418  *  @capability None
       
   419  */
       
   420 EXPORT_C void  CSmsHyperLinkOperations::RemoveAllHyperLinksL() const
       
   421 	{
       
   422 	LOGGSMU1("CSmsHyperLinkOperations::RemoveAllHyperLinks");
       
   423 
       
   424 	ValidateOperationL();
       
   425 
       
   426 	TSmsInformationElementCategories::TInformationElementCategory category;
       
   427 
       
   428 	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsHyperLinkFormat, category) == EFalse)
       
   429 		{
       
   430 		User::Leave(KErrArgument);
       
   431 		}
       
   432 
       
   433 	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
       
   434 	TUint i = additionalAttributes->NumberOfControlInformationElements(category);
       
   435 
       
   436 	while (i-- != 0)
       
   437 	    {
       
   438 	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
       
   439 	    
       
   440 	    // If function leaves, allow the error to propagate upwards
       
   441 	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
       
   442 
       
   443 	    if (id == CSmsInformationElement::ESmsHyperLinkFormat)
       
   444 	        {
       
   445 	        additionalAttributes->DeleteControlInformationElement(category, i);
       
   446 	        }
       
   447 	    }
       
   448 	} // CSmsHyperLinkOperations::RemoveAllHyperLinksL
       
   449 
       
   450 
       
   451 /**
       
   452  *  @publishedAll
       
   453  *  
       
   454  *  Removes the indexed hyperlink from this message.
       
   455  *  
       
   456  *  @param aIndex
       
   457  *  aIndex has the range [0..[n-1]] where n is the
       
   458  *  value returned by NumberOfHyperLinks()
       
   459  *  @leave KErrNotSupported
       
   460  *  If the message version or type does not support hyperlinks.
       
   461  *  @leave KErrArgument
       
   462  *  If the index is out of range.
       
   463  *  @capability None
       
   464  */
       
   465 EXPORT_C void  CSmsHyperLinkOperations::RemoveHyperLinkL(TUint aIndex) const
       
   466 	{
       
   467 	LOGGSMU1("CSmsHyperLinkOperations::RemoveHyperLink");
       
   468 
       
   469 	ValidateOperationL();
       
   470 
       
   471 	TUint numberOfHyperLinks = 0;
       
   472 
       
   473 	TSmsInformationElementCategories::TInformationElementCategory category;
       
   474 
       
   475 	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsHyperLinkFormat, category) == EFalse)
       
   476 		{
       
   477 		User::Leave(KErrArgument);
       
   478 		}
       
   479 
       
   480 	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
       
   481 	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
       
   482 
       
   483 	if (aIndex >= numberOfElements)
       
   484 	    {
       
   485 	    User::Leave(KErrArgument);
       
   486 	    }
       
   487 
       
   488 	for (TUint i = 0; i < numberOfElements; i++)
       
   489 	    {
       
   490 	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
       
   491 
       
   492 	    // If function leaves, allow the error to propagate upwards
       
   493 	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
       
   494 
       
   495 	    if ((id == CSmsInformationElement::ESmsHyperLinkFormat) &&
       
   496 	        (numberOfHyperLinks++ == aIndex))
       
   497 	        {
       
   498 	        additionalAttributes->DeleteControlInformationElement(category, i);
       
   499 	        break;
       
   500 	        }
       
   501 	    }
       
   502 	} // CSmsHyperLinkOperations::RemoveHyperLinkL
       
   503 
       
   504 
       
   505 /**
       
   506  *  @internalComponent
       
   507  *  
       
   508  *  Prevent clients from using the assignment operator by including it in the class definition
       
   509  *  but making it protected and not exporting it.
       
   510  *  
       
   511  *  @capability None
       
   512  */
       
   513 void CSmsReplyAddressOperations::operator=(const CSmsReplyAddressOperations&)
       
   514     {
       
   515     // Ignore in code coverage - not intended to be used
       
   516     BULLSEYE_OFF    
       
   517     LOGGSMU1("CSmsReplyAddressOperations::operator=");
       
   518     Panic(KGsmuPanicMethodBodyNotImplemented1);
       
   519     BULLSEYE_RESTORE
       
   520     }
       
   521 
       
   522 /**
       
   523  *  @internalComponent
       
   524  *  
       
   525  *  Prevent clients from using the equality operator by including it in the class definition
       
   526  *  but making it protected and not exporting it.
       
   527  *  
       
   528  *  @capability None
       
   529  */
       
   530 TBool CSmsReplyAddressOperations::operator==(const CSmsReplyAddressOperations&)
       
   531     {
       
   532     // Ignore in code coverage - not intended to be used
       
   533     BULLSEYE_OFF    
       
   534     LOGGSMU1("CSmsReplyAddressOperations::operator==");
       
   535     Panic(KGsmuPanicMethodBodyNotImplemented1);
       
   536     return EFalse;
       
   537     BULLSEYE_RESTORE
       
   538     }
       
   539 
       
   540 /**
       
   541  *  @internalComponent
       
   542  *  
       
   543  *  Identifies whether the message type or version supports this operation
       
   544  *  
       
   545  *  @leave
       
   546  *  If the message type or version does not support this operation.
       
   547  */
       
   548 void CSmsReplyAddressOperations::ValidateOperationL() const
       
   549 	{
       
   550 	LOGGSMU1("CSmsReplyAddressOperations::ValidateOperationL()");
       
   551 
       
   552 	if (iMessage.Version() < CSmsMessage::ESmsMessageV1)
       
   553 	    {
       
   554 	    LOGGSMU2("CSmsReplyAddressOperations::AddReplyAddressL, Operation not supported, Msg Version %d", iMessage.Version());
       
   555 	    User::Leave(KErrNotSupported);
       
   556 	    }
       
   557 
       
   558 	if (!MessageTypeSupported())
       
   559 	    {
       
   560 	    LOGGSMU2("CSmsReplyAddressOperations::AddReplyAddressL, Operation not supported by this PDU type, type = %d", iMessage.Type());
       
   561 	    User::Leave(KErrNotSupported);
       
   562 	    }
       
   563 	} // CSmsReplyAddressOperations::ValidateOperationL
       
   564 
       
   565 
       
   566 /**
       
   567  *  @publishedAll
       
   568  *  
       
   569  *  Adds a reply address information element.
       
   570  *  
       
   571  *  @param aAddress
       
   572  *  The international number to be used in the reply address.
       
   573  *  @leave KErrNotSupported
       
   574  *  If the message version or type does not support a reply addresses.
       
   575  *  @leave KErrAlreadyExists
       
   576  *  If the message already contains a reply address.
       
   577  *  @capability None
       
   578  */
       
   579 EXPORT_C void  CSmsReplyAddressOperations::AddReplyAddressL(const TDesC& aAddress) const
       
   580 	{
       
   581 	LOGGSMU1("CSmsReplyAddressOperations::AddReplyAddressL()");
       
   582 
       
   583 	ValidateOperationL();
       
   584 
       
   585 	if (ContainsReplyAddressIEL())
       
   586 	    {
       
   587 	    LOGGSMU1("CSmsReplyAddressOperations::AddReplyAddressL, Already Exists");
       
   588 	    User::Leave(KErrAlreadyExists);
       
   589 	    }
       
   590 
       
   591 	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
       
   592 
       
   593 	CSmsAddress* address = CSmsAddress::NewL(iCharacterSetConverter,iFs); // needed for encoding the address into the IE.
       
   594 	CleanupStack::PushL(address);
       
   595 	address->SetAddressL(aAddress);
       
   596 	TBuf8<CSmsAddress::KSmsAddressMaxAddressLength> addressBuffer;
       
   597 	addressBuffer.SetLength(CSmsAddress::KSmsAddressMaxAddressLength);
       
   598 	TUint8* startPtr = &addressBuffer[0];
       
   599 	TUint8* endPtr = address->EncodeL(startPtr);
       
   600 	TInt length = 0;
       
   601 	(endPtr > startPtr) ? (length = endPtr - startPtr) : (length = startPtr - endPtr);
       
   602 	addressBuffer.SetLength(length);
       
   603 	CleanupStack::PopAndDestroy(address);
       
   604 
       
   605 	CSmsInformationElement* iE = CSmsInformationElement::NewL(CSmsInformationElement::ESmsReplyAddressFormat, addressBuffer);
       
   606 	CleanupStack::PushL(iE);
       
   607 	additionalAttributes.AddControlInformationElementL(iE);
       
   608 	CleanupStack::Pop(iE);
       
   609 	} // CSmsReplyAddressOperations::AddReplyAddressL
       
   610 
       
   611 
       
   612 /**
       
   613  *  @publishedAll
       
   614  *  
       
   615  *  Adds a reply address information element.
       
   616  *  
       
   617  *  @param aAddress
       
   618  *  Sets To and From addresses in ETSI format.
       
   619  *  @leave KErrNotSupported
       
   620  *  If the message version or type does not support a reply addresses.
       
   621  *  @leave KErrAlreadyExists
       
   622  *  If the message already contains a reply address.
       
   623  *  @capability None
       
   624  */
       
   625 EXPORT_C void  CSmsReplyAddressOperations::AddParsedReplyAddressL(const TGsmSmsTelNumber& aParsedAddress) const
       
   626 	{
       
   627 	LOGGSMU1("CSmsReplyAddressOperations::AddParsedReplyAddressL");
       
   628 
       
   629 	ValidateOperationL();
       
   630 
       
   631 	if (ContainsReplyAddressIEL())
       
   632 	    {
       
   633 	    LOGGSMU1("CSmsReplyAddressOperations::AddParsedReplyAddressL, Already Exists");
       
   634 	    User::Leave(KErrAlreadyExists);
       
   635 	    }
       
   636 
       
   637 	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
       
   638 
       
   639 	CSmsAddress* address = CSmsAddress::NewL(iCharacterSetConverter,iFs);
       
   640 	CleanupStack::PushL(address);
       
   641 	address->SetParsedAddressL(aParsedAddress);
       
   642 	TBuf8<CSmsAddress::KSmsAddressMaxAddressLength> addressBuffer;
       
   643 	addressBuffer.SetLength(CSmsAddress::KSmsAddressMaxAddressLength);
       
   644 	TUint8* startPtr = &addressBuffer[0];
       
   645 	TUint8* endPtr = address->EncodeL(startPtr);
       
   646 	TInt length = 0;
       
   647 	(endPtr > startPtr) ? (length = endPtr - startPtr) : (length = startPtr - endPtr);
       
   648 	addressBuffer.SetLength(length);
       
   649 	CleanupStack::PopAndDestroy(address);
       
   650 
       
   651 	CSmsInformationElement* iE = CSmsInformationElement::NewL(CSmsInformationElement::ESmsReplyAddressFormat, addressBuffer);
       
   652 	CleanupStack::PushL(iE);
       
   653 	additionalAttributes.AddControlInformationElementL(iE);
       
   654 	CleanupStack::Pop(iE);
       
   655 	} // CSmsReplyAddressOperations::AddParsedReplyAddressL
       
   656 
       
   657 
       
   658 /**
       
   659  *  @publishedAll
       
   660  *  
       
   661  *  Identifies whether a reply address has already been added to this
       
   662  *  CSmsMessage using the CSmsReplyAddressOperations interface.
       
   663  *  
       
   664  *  @return
       
   665  *  True if the reply address has already been added using this interface.
       
   666  *  @leave KErrNotSupported
       
   667  *  If the message version or type does not support this query.
       
   668  *  @capability None
       
   669  */
       
   670 EXPORT_C TBool CSmsReplyAddressOperations::ContainsReplyAddressIEL() const
       
   671 	{
       
   672 	LOGGSMU1("CSmsReplyAddressOperations::ContainsReplyAddressIEL()");
       
   673 
       
   674 	TBool rc = EFalse;
       
   675 
       
   676 	ValidateOperationL();
       
   677 
       
   678 	TSmsInformationElementCategories::TInformationElementCategory category;
       
   679 
       
   680 	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsReplyAddressFormat, category) == EFalse)
       
   681 		{
       
   682 		User::Leave(KErrArgument);
       
   683 		}
       
   684 
       
   685 	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
       
   686 	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
       
   687 
       
   688 	for (TUint i = 0; i < numberOfElements; i++)
       
   689 	    {
       
   690 	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
       
   691 	    
       
   692 	    // If function leaves, allow the error to propagate upwards
       
   693 	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
       
   694 
       
   695 	    if (id == CSmsInformationElement::ESmsReplyAddressFormat)
       
   696 	        {
       
   697 	        rc = ETrue;
       
   698 	        break;
       
   699 	        }
       
   700 	    }
       
   701 
       
   702 	return rc;
       
   703 	} // CSmsReplyAddressOperations::ContainsReplyAddressIEL
       
   704 
       
   705 
       
   706 /**
       
   707  *  @publishedAll
       
   708  *  
       
   709  *  Returns the reply address as an international number
       
   710  *  
       
   711  *  @return
       
   712  *  The reply address as an international number.
       
   713  *  @leave KErrNotSupported
       
   714  *  If the message version or type does not support this query.
       
   715  *  @leave KErrNotFound
       
   716  *  If the message does not contain a reply address information element.
       
   717  *  @leave KErrCorrupt
       
   718  *  If the reply address is corrupt
       
   719  *  @capability None
       
   720  */
       
   721 EXPORT_C HBufC* CSmsReplyAddressOperations::GetReplyAddressL() const
       
   722 	{
       
   723 	LOGGSMU1("CSmsReplyAddressOperations::GetReplyAddressL");
       
   724 
       
   725 	ValidateOperationL();
       
   726 
       
   727 	TBool found = EFalse;
       
   728 
       
   729 	CSmsAddress* address = CSmsAddress::NewL(iCharacterSetConverter,iFs);
       
   730 	CleanupStack::PushL(address);
       
   731 
       
   732 	TSmsInformationElementCategories::TInformationElementCategory category;
       
   733 
       
   734 	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsReplyAddressFormat, category) == EFalse)
       
   735 		{
       
   736 		User::Leave(KErrArgument);
       
   737 		}
       
   738 
       
   739 	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
       
   740 	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
       
   741 
       
   742 	for (TUint i = 0; i < numberOfElements; i++)
       
   743 	    {
       
   744 	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
       
   745 	    
       
   746 	    // If function leaves, allow the error to propagate upwards
       
   747 	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
       
   748 
       
   749 	    if (id == CSmsInformationElement::ESmsReplyAddressFormat)
       
   750 	        {
       
   751 	        TGsmuLex8 encodedAddress(additionalAttributes->GetControlInformationElementL(category, i).Data());
       
   752 	        TRAPD(err,address->DecodeL(encodedAddress));
       
   753 
       
   754 	        if (err == KErrNone)
       
   755 	            {
       
   756 	            found = ETrue;
       
   757 	            break;
       
   758 	            }
       
   759 	        else
       
   760 	            {
       
   761 	            User::Leave(KErrCorrupt);
       
   762 	            }
       
   763 	        }
       
   764 	    }
       
   765 
       
   766 	HBufC* buf = NULL;
       
   767 	if (found)
       
   768 	    {
       
   769 	    buf = HBufC::NewL(TGsmSmsTelNumberMaxLen); // 20 characters preceeded by '+'
       
   770 	    *buf = address->Address();
       
   771 	    }
       
   772 	else
       
   773 	    {
       
   774 	    User::Leave(KErrNotFound);
       
   775 	    }
       
   776 
       
   777 	CleanupStack::PopAndDestroy(address);
       
   778 
       
   779 	return buf;
       
   780 	} // CSmsReplyAddressOperations::GetReplyAddressL
       
   781 
       
   782 
       
   783 /**
       
   784  *  @publishedAll
       
   785  *  
       
   786  *  Returns the reply address in ETSI format.
       
   787  *  
       
   788  *  @return
       
   789  *  True, if the CSmsMessage contains a reply address.
       
   790  *  False, otherwise
       
   791  *  @leave KErrNotSupported
       
   792  *  If the message version or type does not support this query.
       
   793  *  @leave KErrCorrupt
       
   794  *  If the reply address is corrupt
       
   795  *  @capability None
       
   796  */
       
   797 EXPORT_C TInt  CSmsReplyAddressOperations::GetParsedReplyAddressL(TGsmSmsTelNumber& aParsedAddress) const
       
   798 	{
       
   799 	LOGGSMU1("CSmsReplyAddressOperations::GetParsedReplyAddressL");
       
   800 
       
   801 	ValidateOperationL();
       
   802 
       
   803 	TBool rc = EFalse;
       
   804 
       
   805 	CSmsAddress* address = CSmsAddress::NewL(iCharacterSetConverter,iFs);
       
   806 	CleanupStack::PushL(address);
       
   807 
       
   808 	TSmsInformationElementCategories::TInformationElementCategory category;
       
   809 
       
   810 	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsReplyAddressFormat, category) == EFalse)
       
   811 		{
       
   812 		User::Leave(KErrArgument);
       
   813 		}
       
   814 
       
   815 	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
       
   816 	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
       
   817 
       
   818 	for (TUint i = 0; i < numberOfElements; i++)
       
   819 	    {
       
   820 	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
       
   821 	    
       
   822 	    // If function leaves, allow the error to propagate upwards
       
   823 	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
       
   824 
       
   825 	    // CSmsAddress is used here for encoding the reply address into an IE.
       
   826 	    // It also used to encode the source / destination address in the CSmsMessage.
       
   827 	    // CSmsAddress::DecodeL expects internally that alphanumeric addresses will be size
       
   828 	    // CSmsAddress::KSmsAddressMaxAddressValueLength=10.
       
   829 	    // Need to add padding bytes to bring the address field up to the maximum size.
       
   830 	    if (id == CSmsInformationElement::ESmsReplyAddressFormat)
       
   831 	        {
       
   832 	        TBuf8<CSmsAddress::KSmsAddressMaxAddressLength> data;
       
   833 	        data = additionalAttributes->GetControlInformationElementL(category, i).Data();
       
   834 	        TUint8 actualDataLength = data.Length();
       
   835 	        data.SetLength(CSmsAddress::KSmsAddressMaxAddressLength);
       
   836 	        for (TUint8 j = actualDataLength; j < CSmsAddress::KSmsAddressMaxAddressLength; j++)
       
   837 	            {
       
   838 	            data[j] = 0;
       
   839 	            }
       
   840 
       
   841 	        TGsmuLex8 encodedAddress(data);
       
   842 	        TRAPD(err,address->DecodeL(encodedAddress));
       
   843 	        if (err==KErrNone)
       
   844 	            {
       
   845 	            address->ParsedAddress(aParsedAddress);
       
   846 	            rc = ETrue;
       
   847 	            break;
       
   848 	            }
       
   849 	        else
       
   850 	            {
       
   851 	            User::Leave(KErrCorrupt);
       
   852 	            }
       
   853 	        }
       
   854 	    }
       
   855 
       
   856 	CleanupStack::PopAndDestroy(address);
       
   857 
       
   858 	return rc;
       
   859 	} // CSmsReplyAddressOperations::GetParsedReplyAddressL
       
   860 
       
   861 
       
   862 /**
       
   863  *  @publishedAll
       
   864  *  
       
   865  *  Removes the reply address information element.
       
   866  *  
       
   867  *  @leave KErrNotSupported
       
   868  *  If the message version or type does not support this query.
       
   869  *  @capability None
       
   870  */
       
   871 EXPORT_C void  CSmsReplyAddressOperations::RemoveReplyAddressL() const
       
   872 	{
       
   873 	LOGGSMU1("CSmsReplyAddressOperations::RemoveReplyAddress");
       
   874 
       
   875 	ValidateOperationL();
       
   876 
       
   877 	TSmsInformationElementCategories::TInformationElementCategory category;
       
   878 
       
   879 	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsReplyAddressFormat, category) == EFalse)
       
   880 		{
       
   881 		User::Leave(KErrArgument);
       
   882 		}
       
   883 
       
   884 	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
       
   885 	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
       
   886 
       
   887 	for (TInt i = 0; i < numberOfElements; i++)
       
   888 	    {
       
   889 	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
       
   890 	    
       
   891 	    // If function leaves, allow the error to propagate upwards
       
   892 	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
       
   893 
       
   894 	    if (id == CSmsInformationElement::ESmsReplyAddressFormat)
       
   895 	        {
       
   896 	        additionalAttributes->DeleteControlInformationElement(category, i);
       
   897 	        break;
       
   898 	        }
       
   899 	    }
       
   900 	} // CSmsReplyAddressOperations::RemoveReplyAddressL
       
   901 
       
   902 
       
   903 CSmsReplyAddressOperations::CSmsReplyAddressOperations(CSmsInformationElement::TSmsInformationElementIdentifier aId,  CSmsMessage& aMessage,
       
   904                                                        CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) : CSmsCtrlOperation(aId, aMessage),
       
   905                                                        iCharacterSetConverter(aCharacterSetConverter), iFs(aFs)
       
   906 	{
       
   907 	//NOP
       
   908 	} // CSmsReplyAddressOperations::CSmsReplyAddressOperations
       
   909 
       
   910 
       
   911 /**
       
   912  *  @internalComponent
       
   913  *  
       
   914  *  Identifies whether the message type or version supports this operation
       
   915  *  
       
   916  *  @leave
       
   917  *  If the message type or version does not support this operation.
       
   918  */
       
   919 void CSmsSpecialSMSMessageOperations::ValidateOperationL() const
       
   920 	{
       
   921 	LOGGSMU1("CSmsSpecialSMSMessageOperations::ValidateOperationL()");
       
   922 
       
   923 	if (iMessage.Version() < CSmsMessage::ESmsMessageV1)
       
   924 	    {
       
   925 	    LOGGSMU2("CSmsSpecialSMSMessageOperations::AddSpecialMessageIndicationL, Operation not supported, version %d", iMessage.Version());
       
   926 	    User::Leave(KErrNotSupported);
       
   927 	    }
       
   928 
       
   929 	if (!MessageTypeSupported())
       
   930 	    {
       
   931 	    LOGGSMU2("CSmsSpecialSMSMessageOperations::AddSpecialMessageIndicationL, Operation not supported by this PDU type, type = %d", iMessage.Type());
       
   932 	    User::Leave(KErrNotSupported);
       
   933 	    }
       
   934 	} // CSmsSpecialSMSMessageOperations::ValidateOperationL
       
   935 
       
   936 
       
   937 /**
       
   938  *  @internalComponent
       
   939  *  
       
   940  *  Prevent clients from using the assignment operator by including it in the class definition
       
   941  *  but making it protected and not exporting it.
       
   942  *  
       
   943  *  @capability None
       
   944  */
       
   945 void CSmsSpecialSMSMessageOperations::operator=(const CSmsSpecialSMSMessageOperations&)
       
   946     {
       
   947     // Ignore in code coverage - not intended to be used
       
   948     BULLSEYE_OFF    
       
   949     LOGGSMU1("CSmsSpecialSMSMessageOperations::operator=");
       
   950     Panic(KGsmuPanicMethodBodyNotImplemented1);
       
   951     BULLSEYE_RESTORE
       
   952     }
       
   953 
       
   954 /**
       
   955  *  @internalComponent
       
   956  *  
       
   957  *  Prevent clients from using the equality operator by including it in the class definition
       
   958  *  but making it protected and not exporting it.
       
   959  *  
       
   960  *  @capability None
       
   961  */
       
   962 TBool CSmsSpecialSMSMessageOperations::operator==(const CSmsSpecialSMSMessageOperations&)
       
   963 	{
       
   964 	LOGGSMU1("CSmsSpecialSMSMessageOperations::operator==");
       
   965 	Panic(KGsmuPanicMethodBodyNotImplemented1);
       
   966 	return EFalse;
       
   967 	} // CSmsSpecialSMSMessageOperations::operator
       
   968 
       
   969 
       
   970 /**
       
   971  *  @publishedAll
       
   972  *  
       
   973  *  Either adds a new or updates an existing special message indication information element.
       
   974  *  
       
   975  *  @param aStore
       
   976  *  Indicates whether or not the message shall be stored.
       
   977  *  @param aMessageIndicationType
       
   978  *  Indicates the basic message type
       
   979  *  @param aExtendedType
       
   980  *  Indicates the extended message type
       
   981  *  @param aProfile
       
   982  *  Indicates the profile ID of the Multiple Subscriber Profile
       
   983  *  @param aMessageCount
       
   984  *  Indicates the number of messages of the type specified in Octet 1 that are waiting
       
   985  *  @leave KErrNotSupported
       
   986  *  If the message version or type does not support this query.
       
   987  *  @capability None
       
   988  */
       
   989 EXPORT_C void CSmsSpecialSMSMessageOperations::AddSpecialMessageIndicationL(TBool aStore,
       
   990                                                                             TSmsMessageIndicationType aMessageIndicationType,
       
   991                                                                             TExtendedSmsIndicationType aExtendedType,
       
   992                                                                             TSmsMessageProfileType aProfile,
       
   993                                                                             TUint8 aMessageCount) const
       
   994 	{
       
   995 	LOGGSMU1("CSmsSpecialSMSMessageOperations::AddSpecialMessageIndicationL");
       
   996 
       
   997 	ValidateOperationL();
       
   998 
       
   999 	CSmsUserData& userData = iMessage.SmsPDU().UserData();
       
  1000 
       
  1001 	TBuf8<2> data;
       
  1002 	data.SetLength(2);
       
  1003 
       
  1004 	data[0] = ( ((TUint8) aMessageIndicationType) +
       
  1005 	            ((TUint8) (aExtendedType << 2))   +
       
  1006 	            ((TUint8) (aProfile      << 5))   +
       
  1007 	            ((TUint8) (aStore        << 7)) );
       
  1008 
       
  1009 	data[1] = aMessageCount;
       
  1010 
       
  1011 	CArrayFixFlat<TInt>* indices = new(ELeave) CArrayFixFlat<TInt>(4);
       
  1012 	CleanupStack::PushL(indices);
       
  1013 	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication, *indices);
       
  1014 
       
  1015 	TBool found = EFalse;
       
  1016 	TInt count = indices->Count();
       
  1017 	for (TInt i=0; ((i<count) && (found==EFalse)); i++)
       
  1018 	    {
       
  1019 		TUint index = indices->operator[](i);
       
  1020 		CSmsInformationElement& ieAlreadyInWorkingPDU = userData.InformationElement(index);
       
  1021 
       
  1022 	    if (ieAlreadyInWorkingPDU.Data()[0] == data[0])
       
  1023 	        {
       
  1024 	        ieAlreadyInWorkingPDU.Data()[1] = data[1];
       
  1025 	        found = ETrue;
       
  1026 	        break;
       
  1027 	        }
       
  1028 	    }
       
  1029 	CleanupStack::PopAndDestroy(indices);
       
  1030 
       
  1031 	if (found == EFalse)
       
  1032 	    {
       
  1033 	    userData.AddInformationElementL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication,data);
       
  1034 	    }
       
  1035 	} // CSmsSpecialSMSMessageOperations::AddSpecialMessageIndicationL
       
  1036 
       
  1037 
       
  1038 /**
       
  1039  *  @publishedAll
       
  1040  *  
       
  1041  *  Gets a count of the number of special message indication information elements which
       
  1042  *  are stored inside the user data.
       
  1043  *  
       
  1044  *  @return The number of special message indication information elements which
       
  1045  *  are stored inside the user data.
       
  1046  *  @leave KErrNotSupported
       
  1047  *  If the message version or type does not support this query.
       
  1048  *  @capability None
       
  1049  */
       
  1050 EXPORT_C TUint CSmsSpecialSMSMessageOperations::GetCountOfSpecialMessageIndicationsL() const
       
  1051 	{
       
  1052 	LOGGSMU1("CSmsSpecialSMSMessageOperations::GetCountOfSpecialMessageIndicationsL()");
       
  1053 
       
  1054 	ValidateOperationL();
       
  1055 
       
  1056 	CSmsUserData& userData = iMessage.SmsPDU().UserData();
       
  1057 
       
  1058 	CArrayFixFlat<TInt>* indices = new (ELeave) CArrayFixFlat<TInt>(8);
       
  1059 	CleanupStack::PushL(indices);
       
  1060 	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication,*indices);
       
  1061 	TUint  count = indices->Count();
       
  1062 	CleanupStack::PopAndDestroy(indices);
       
  1063 
       
  1064 	return count;
       
  1065 	} // CSmsSpecialSMSMessageOperations::GetCountOfSpecialMessageIndicationsL
       
  1066 
       
  1067 
       
  1068 /**
       
  1069  *  @publishedAll
       
  1070  *  
       
  1071  *  Gets the attributes of the Special Message Indication specified by aIndex.
       
  1072  *  
       
  1073  *  @param aIndex
       
  1074  *  aIndex is a value less than GetCountOfSpecialMessageIndications().
       
  1075  *  @param aStore
       
  1076  *  Indicates whether or not the message shall be stored.
       
  1077  *  @param aMessageIndicationType
       
  1078  *  Indicates the basic message type
       
  1079  *  @param aExtendedType
       
  1080  *  Indicates the extended message type
       
  1081  *  @param aProfile
       
  1082  *  Indicates the profile ID of the Multiple Subscriber Profile
       
  1083  *  @param aMessageCount
       
  1084  *  Indicates the number of messages of the type specified in Octet 1 that are waiting
       
  1085  *  @leave KErrNotSupported
       
  1086  *  If the message version or type does not support this query.
       
  1087  *  @leave KErrArgument
       
  1088  *  If aIndex is >= GetCountOfSpecialMessageIndications()
       
  1089  *  @capability None
       
  1090  */
       
  1091 EXPORT_C void CSmsSpecialSMSMessageOperations::GetMessageIndicationIEL(TUint aIndex,
       
  1092                                                                        TBool& aStore,
       
  1093                                                                        TSmsMessageIndicationType& aMessageIndicationType,
       
  1094                                                                        TExtendedSmsIndicationType& aExtendedType,
       
  1095                                                                        TSmsMessageProfileType&  aProfile,
       
  1096                                                                        TUint8& aMessageCount) const
       
  1097 	{
       
  1098 	LOGGSMU1("CSmsSpecialSMSMessageOperations::GetMessageIndicationIEL()");
       
  1099 
       
  1100 	ValidateOperationL();
       
  1101 
       
  1102 	CSmsUserData& userData = iMessage.SmsPDU().UserData();
       
  1103 
       
  1104 	CArrayFixFlat<TInt>* indices = new (ELeave) CArrayFixFlat<TInt>(8);
       
  1105 	CleanupStack::PushL(indices);
       
  1106 	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication,*indices);
       
  1107 
       
  1108 	if (aIndex < indices->Count())
       
  1109 	    {
       
  1110 	    CSmsInformationElement& informationElement = userData.InformationElement((*indices)[aIndex]);
       
  1111 
       
  1112 	    aMessageIndicationType =  (TSmsMessageIndicationType)   (informationElement.Data()[0]       & 0x03);
       
  1113 	    aExtendedType          =  (TExtendedSmsIndicationType) ((informationElement.Data()[0] >> 2) & 0x07);
       
  1114 	    aProfile               =  (TSmsMessageProfileType)     ((informationElement.Data()[0] >> 5) & 0x03);
       
  1115 	    aStore                 =  (TBool)                      ((informationElement.Data()[0] >> 7) & 0x01);
       
  1116 	    aMessageCount          =  (TUint8)                      (informationElement.Data()[1]);
       
  1117 	    }
       
  1118 	else
       
  1119 	    {
       
  1120 	    User::Leave(KErrArgument);
       
  1121 	    }
       
  1122 
       
  1123 	CleanupStack::PopAndDestroy(indices);
       
  1124 	} // CSmsSpecialSMSMessageOperations::GetMessageIndicationIEL
       
  1125 
       
  1126 
       
  1127 /**
       
  1128  *  @publishedAll
       
  1129  *  
       
  1130  *  Removes the Special Message Indication specified by the input attributes, provided it exists.
       
  1131  *  
       
  1132  *  @param aMessageIndicationType
       
  1133  *  Indicates the basic message type
       
  1134  *  @param aExtendedType
       
  1135  *  Indicates the extended message type
       
  1136  *  @leave KErrNotSupported
       
  1137  *  If the message version or type does not support this query.
       
  1138  *  @capability None
       
  1139  */
       
  1140 EXPORT_C void CSmsSpecialSMSMessageOperations::RemoveSpecialMessageIndicationL(TSmsMessageIndicationType aMessageIndicationType, TExtendedSmsIndicationType aExtendedType) const
       
  1141 	{
       
  1142 	LOGGSMU1("CSmsSpecialSMSMessageOperations::RemoveAllSpecialMessageIndications");
       
  1143 
       
  1144 	ValidateOperationL();
       
  1145 
       
  1146 	CSmsUserData& userData = iMessage.SmsPDU().UserData();
       
  1147 
       
  1148 	CArrayFixFlat<TInt>* indices = new (ELeave) CArrayFixFlat<TInt>(8);
       
  1149 	CleanupStack::PushL(indices);
       
  1150 	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication,*indices);
       
  1151 
       
  1152 	TUint i = indices->Count();
       
  1153 
       
  1154 	while (i-- != 0)
       
  1155 	    {
       
  1156 	    CSmsInformationElement& informationElement = userData.InformationElement((*indices)[i]);
       
  1157 
       
  1158 	    TSmsMessageIndicationType          type = ((TSmsMessageIndicationType)   (informationElement.Data()[0]       & 0x03));
       
  1159 	    TExtendedSmsIndicationType extendedType =  (TExtendedSmsIndicationType) ((informationElement.Data()[0] >> 2) & 0x07);
       
  1160 
       
  1161 	    if ( (aMessageIndicationType == type) &&
       
  1162 	         (aExtendedType == extendedType) )
       
  1163 	        {
       
  1164 	        userData.RemoveInformationElement((*indices)[i]);
       
  1165 	        break;
       
  1166 	        }
       
  1167 	    }
       
  1168 
       
  1169 	CleanupStack::PopAndDestroy(indices);
       
  1170 	} // CSmsSpecialSMSMessageOperations::RemoveSpecialMessageIndicationL
       
  1171 
       
  1172 
       
  1173 /**
       
  1174  *  @publishedAll
       
  1175  *  
       
  1176  *  Removes all Special Message Indications Information Elements contained in the message.
       
  1177  *  
       
  1178  *  @leave KErrNotSupported
       
  1179  *  If the message version or type does not support this query.
       
  1180  *  @capability None
       
  1181  */
       
  1182 EXPORT_C void CSmsSpecialSMSMessageOperations::RemoveAllSpecialMessageIndicationsL() const
       
  1183 	{
       
  1184 	LOGGSMU1("CSmsSpecialSMSMessageOperations::RemoveAllSpecialMessageIndicationsL");
       
  1185 
       
  1186 	ValidateOperationL();
       
  1187 
       
  1188 	CSmsUserData& userData = iMessage.SmsPDU().UserData();
       
  1189 
       
  1190 	CArrayFixFlat<TInt>* indices = new (ELeave) CArrayFixFlat<TInt>(8);
       
  1191 	CleanupStack::PushL(indices);
       
  1192 	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISpecialSMSMessageIndication,*indices);
       
  1193 
       
  1194 	TUint i = indices->Count();
       
  1195 
       
  1196 	while (i-- != 0)
       
  1197 	   {
       
  1198 	   userData.RemoveInformationElement((*indices)[i]);
       
  1199 	   }
       
  1200 
       
  1201 	CleanupStack::PopAndDestroy(indices);
       
  1202 	} // CSmsSpecialSMSMessageOperations::RemoveAllSpecialMessageIndicationsL
       
  1203 
       
  1204 
       
  1205 CSmsSpecialSMSMessageOperations::CSmsSpecialSMSMessageOperations(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage) : CSmsCtrlOperation(aId, aMessage)
       
  1206 	{
       
  1207 	//NOP
       
  1208 	} // CSmsSpecialSMSMessageOperations::CSmsSpecialSMSMessageOperations
       
  1209 
       
  1210 
       
  1211 /**
       
  1212  *  @internalComponent
       
  1213  *  
       
  1214  *  Prevent clients from using the assignment operator by including it in the class definition
       
  1215  *  but making it protected and not exporting it.
       
  1216  *  
       
  1217  *  @capability None
       
  1218  */
       
  1219 void CSmsEnhancedVoiceMailOperations::operator=(const CSmsEnhancedVoiceMailOperations&)
       
  1220     {
       
  1221     // Ignore in code coverage - not intended to be used
       
  1222     BULLSEYE_OFF    
       
  1223     LOGGSMU1("CSmsEnhancedVoiceMailOperations::operator=");
       
  1224     Panic(KGsmuPanicMethodBodyNotImplemented1);
       
  1225     BULLSEYE_RESTORE
       
  1226     }
       
  1227 
       
  1228 /**
       
  1229  *  @internalComponent
       
  1230  *  
       
  1231  *  Prevent clients from using the equality operator by including it in the class definition
       
  1232  *  but making it protected and not exporting it.
       
  1233  *  
       
  1234  *  @capability None
       
  1235  */
       
  1236 TBool CSmsEnhancedVoiceMailOperations::operator==(const CSmsEnhancedVoiceMailOperations&)
       
  1237     {
       
  1238     // Ignore in code coverage - not intended to be used
       
  1239     BULLSEYE_OFF    
       
  1240     LOGGSMU1("CSmsEnhancedVoiceMailOperations::operator==");
       
  1241     Panic(KGsmuPanicMethodBodyNotImplemented1);
       
  1242     return EFalse;
       
  1243     BULLSEYE_RESTORE
       
  1244     }
       
  1245 
       
  1246 /**
       
  1247  *  @internalComponent
       
  1248  *  
       
  1249  *  Identifies whether the message type or version supports this operation
       
  1250  *  
       
  1251  *  @leave
       
  1252  *  If the message type or version does not support this operation.
       
  1253  */
       
  1254 void CSmsEnhancedVoiceMailOperations::ValidateOperationL() const
       
  1255 	{
       
  1256 	LOGGSMU1("CSmsEnhancedVoiceMailOperations::ValidateOperationL()");
       
  1257 
       
  1258 	if (iMessage.Version() < CSmsMessage::ESmsMessageV1)
       
  1259 	    {
       
  1260 	    LOGGSMU2("CSmsEnhancedVoiceMailInformation::AddEnhancedVoiceMailIEL, Operation not supported, Msg Version %d", iMessage.Version());
       
  1261 	    User::Leave(KErrNotSupported);
       
  1262 	    }
       
  1263 
       
  1264 	if (!MessageTypeSupported())
       
  1265 	    {
       
  1266 	    LOGGSMU2("CSmsSpecialSMSMessageOperations::AddEnhancedVoiceMailIEL, Operation not supported by this PDU type, type = %d", iMessage.Type());
       
  1267 	    User::Leave(KErrNotSupported);
       
  1268 	    }
       
  1269 	} // CSmsEnhancedVoiceMailOperations::ValidateOperationL
       
  1270 
       
  1271 
       
  1272 /**
       
  1273  *  @publishedAll
       
  1274  *  
       
  1275  *  Adds an Enhanced Voice Mail Information Element to the CSmsMessage.
       
  1276  *  The information element can be either an Enhanced Voice Mail Notification or
       
  1277  *  an Enhanced Voice Mail Delete Confirmation. Enhanced Voice Mail Notifications
       
  1278  *  and Enhanced Voice Mail Delete Confirmations are abstracted in classes derived
       
  1279  *  from CEnhancedVoiceMailBoxInformation.
       
  1280  *  @param aEVMI
       
  1281  *  A pointer to the Enhanced Voice Mail Information Element.
       
  1282  *  @leave KErrNotSupported
       
  1283  *  If the message version or type does not support this query.
       
  1284  *  @leave KErrAlreadyExists
       
  1285  *  If an Enhanced Voice Mail Information Element has already been installed.
       
  1286  *  @leave KErrArgument
       
  1287  *  If the input parameter contains invalid parameters.
       
  1288  *  @capability None
       
  1289  */
       
  1290 EXPORT_C void CSmsEnhancedVoiceMailOperations::AddEnhancedVoiceMailIEL(const CEnhancedVoiceMailBoxInformation& aEVMI) const
       
  1291 	{
       
  1292 	LOGGSMU1("CSmsEnhancedVoiceMailInformation::AddEnhancedVoiceMailIEL");
       
  1293 
       
  1294 	ValidateOperationL();
       
  1295 
       
  1296 	if (ContainsEnhancedVoiceMailIEL())
       
  1297 	    {
       
  1298 	    LOGGSMU1("CSmsEnhancedVoiceMailInformation::AddEnhancedVoiceMailIEL, Already Exists");
       
  1299 	    User::Leave(KErrAlreadyExists);
       
  1300 	    }
       
  1301 
       
  1302 	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
       
  1303 
       
  1304 	// The Enhanced Voice Mail Information Element must fit into a single PDU.
       
  1305 	// The maximum size for its data field is therefore
       
  1306 	// the maximum size of the user data minus user data header length, the ie identifier byte and
       
  1307 	// ie length byte.
       
  1308 	TBuf8<CEnhancedVoiceMailBoxInformation::KSmsMaxEnhancedVoiceMailSize> voiceMailInfo;
       
  1309 	voiceMailInfo.SetLength(CEnhancedVoiceMailNotification::KSmsMaxEnhancedVoiceMailSize);
       
  1310 	TUint8* startPtr = &voiceMailInfo[0];
       
  1311 	TUint8* endPtr = aEVMI.EncodeL(startPtr, iCharacterSetConverter, iFs);
       
  1312 	TInt length = (TInt) (endPtr - startPtr);
       
  1313 	voiceMailInfo.SetLength(length);
       
  1314 
       
  1315 	CSmsInformationElement* iE = CSmsInformationElement::NewL(CSmsInformationElement::CSmsInformationElement::ESmsEnhanceVoiceMailInformation, voiceMailInfo);
       
  1316 	CleanupStack::PushL(iE);
       
  1317 
       
  1318 	additionalAttributes.AddControlInformationElementL(iE);
       
  1319 	CleanupStack::Pop();
       
  1320 	} // CSmsEnhancedVoiceMailOperations::AddEnhancedVoiceMailIEL
       
  1321 
       
  1322 
       
  1323 /**
       
  1324  *  @publishedAll
       
  1325  *  
       
  1326  *  Removes the Enhanced Voice Mail Information Element from the CSmsMessage,
       
  1327  *  provided it exists.
       
  1328  *  @leave KErrNotSupported
       
  1329  *  If the message version or type does not support this query.
       
  1330  *  @leave KErrNotFound
       
  1331  *  If the CSmsMessage does not contain an Enhanced Voice Mail Information Element
       
  1332  *  @capability None
       
  1333  */
       
  1334 EXPORT_C CEnhancedVoiceMailBoxInformation* CSmsEnhancedVoiceMailOperations::RemoveEnhancedVoiceMailIEL() const
       
  1335 	{
       
  1336 	LOGGSMU1("CSmsEnhancedVoiceMailInformation::RemoveEnhancedVoiceMailIE");
       
  1337 
       
  1338 	ValidateOperationL();
       
  1339 
       
  1340 	CEnhancedVoiceMailBoxInformation* voiceMailBoxInfo = NULL;
       
  1341 	TBool deleteInformationElement = ETrue;
       
  1342 	
       
  1343 	// If function leaves, allow the error to propagate upwards
       
  1344 	voiceMailBoxInfo = GetEnhancedVoiceMailIEL(deleteInformationElement);
       
  1345 
       
  1346 	return voiceMailBoxInfo;
       
  1347 	} // CSmsEnhancedVoiceMailOperations::RemoveEnhancedVoiceMailIEL
       
  1348 
       
  1349 
       
  1350 /**
       
  1351  *  @publishedAll
       
  1352  *  
       
  1353  *  Copies the Enhanced Voice Mail Information Element contained in the CSmsMessage,
       
  1354  *  provided one exists.
       
  1355  *  @leave KErrNotSupported
       
  1356  *  If the message version or type does not support this query.
       
  1357  *  @leave KErrNotFound
       
  1358  *  If the CSmsMessage does not contain an Enhanced Voice Mail Information Element to copy.
       
  1359  *  @capability None
       
  1360  */
       
  1361 EXPORT_C CEnhancedVoiceMailBoxInformation* CSmsEnhancedVoiceMailOperations::CopyEnhancedVoiceMailIEL() const
       
  1362 	{
       
  1363 	LOGGSMU1("CSmsEnhancedVoiceMailInformation::CopyEnhancedVoiceMailIEL");
       
  1364 
       
  1365 	ValidateOperationL();
       
  1366 
       
  1367 	CEnhancedVoiceMailBoxInformation* voiceMailBoxInfo = NULL;
       
  1368 	TBool deleteInformationElement = EFalse;
       
  1369 	
       
  1370 	// If function leaves, allow the error to propagate upwards
       
  1371 	voiceMailBoxInfo = GetEnhancedVoiceMailIEL(deleteInformationElement);
       
  1372 
       
  1373 	return voiceMailBoxInfo;
       
  1374 	} // CSmsEnhancedVoiceMailOperations::CopyEnhancedVoiceMailIEL
       
  1375 
       
  1376 
       
  1377 /**
       
  1378  *  @internalComponent
       
  1379  *  
       
  1380  *  Returns a copy of the Enhanced Voice Mail Information Element contained in the CSmsMessage,
       
  1381  *  provided one exists. Optionally deletes the information element.
       
  1382  *  @param aRemove
       
  1383  *  Indicates that the information element should be deleted once its contents have been copied.
       
  1384  *  @leave KErrNotFound
       
  1385  *  If the CSmsMessage does not contain an Enhanced Voice Mail Information Element to copy.
       
  1386  */
       
  1387 CEnhancedVoiceMailBoxInformation* CSmsEnhancedVoiceMailOperations::GetEnhancedVoiceMailIEL(TBool aRemove) const
       
  1388 	{
       
  1389 	LOGGSMU1("CSmsEnhancedVoiceMailOperations::GetEnhancedVoiceMailIEL()");
       
  1390 
       
  1391 	TBool found = EFalse;
       
  1392 
       
  1393 	CEnhancedVoiceMailBoxInformation* voiceMailBoxInfo = NULL;
       
  1394 
       
  1395 	TSmsInformationElementCategories::TInformationElementCategory category;
       
  1396 
       
  1397 	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsEnhanceVoiceMailInformation, category) == EFalse)
       
  1398 		{
       
  1399 		User::Leave(KErrArgument);
       
  1400 		}
       
  1401 
       
  1402 	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
       
  1403 	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
       
  1404 
       
  1405 	for (TUint i = 0; i < numberOfElements; i++)
       
  1406 	    {
       
  1407 	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
       
  1408 	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
       
  1409 
       
  1410 	    if (id == CSmsInformationElement::CSmsInformationElement::ESmsEnhanceVoiceMailInformation)
       
  1411 	        {
       
  1412 	        if (additionalAttributes->GetControlInformationElementL(category, i).Data()[0] & 0x01)
       
  1413 	            {
       
  1414 	            voiceMailBoxInfo = CEnhancedVoiceMailDeleteConfirmations::NewL();
       
  1415 	            }
       
  1416 	        else
       
  1417 	            {
       
  1418 	            voiceMailBoxInfo = CEnhancedVoiceMailNotification::NewL();
       
  1419 	            }
       
  1420 
       
  1421 	        CleanupStack::PushL(voiceMailBoxInfo);
       
  1422 	        TGsmuLex8 encodedVoiceMailBox(additionalAttributes->GetControlInformationElementL(category, i).Data());
       
  1423 	        voiceMailBoxInfo->DecodeL(encodedVoiceMailBox, iCharacterSetConverter, iFs);
       
  1424 	        CleanupStack::Pop(voiceMailBoxInfo);
       
  1425 
       
  1426 	        if (aRemove)
       
  1427 	            {
       
  1428 	            additionalAttributes->DeleteControlInformationElement(category, i);
       
  1429 	            }
       
  1430 
       
  1431 	        found = ETrue;
       
  1432 
       
  1433 	        break;
       
  1434 	        }
       
  1435 	    }
       
  1436 
       
  1437 	if (found == EFalse)
       
  1438 	    {
       
  1439 	    User::Leave(KErrNotFound);
       
  1440 	    }
       
  1441 
       
  1442 	return voiceMailBoxInfo;
       
  1443 	} // CSmsEnhancedVoiceMailOperations::GetEnhancedVoiceMailIEL
       
  1444 
       
  1445 
       
  1446 /**
       
  1447  *  @publishedAll
       
  1448  *  
       
  1449  *  Determines whether the CSmsMessage contains an Enhanced Voice Mail Information Element.
       
  1450  *  @leave KErrNotSupported
       
  1451  *  If the message version or type does not support this query.
       
  1452  *  @return
       
  1453  *  True if the CSmsMessage contains an Enhanced Voice Mail Information Element.
       
  1454  *  @capability None
       
  1455  */
       
  1456 EXPORT_C TBool CSmsEnhancedVoiceMailOperations::ContainsEnhancedVoiceMailIEL() const
       
  1457 	{
       
  1458 	LOGGSMU1("CSmsEnhancedVoiceMailInformation::ContainsEnhancedVoiceMailIEL");
       
  1459 
       
  1460 	ValidateOperationL();
       
  1461 
       
  1462 	TBool rc = EFalse;
       
  1463 
       
  1464 	TSmsInformationElementCategories::TInformationElementCategory category;
       
  1465 
       
  1466 	if (TSmsInformationElementCategories::GetCategoryDefinition(CSmsInformationElement::ESmsEnhanceVoiceMailInformation, category) == EFalse)
       
  1467 		{
       
  1468 		User::Leave(KErrArgument);
       
  1469 		}
       
  1470 
       
  1471 	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
       
  1472 	TUint numberOfElements = additionalAttributes->NumberOfControlInformationElements(category);
       
  1473 
       
  1474 	for (TUint i = 0; i < numberOfElements; i++)
       
  1475 	    {
       
  1476 	    CSmsInformationElement::TSmsInformationElementIdentifier id = CSmsInformationElement::ESmsIEMaximum;
       
  1477 	    
       
  1478 	    // If function leaves, allow the error to propagate upwards
       
  1479 	    id = additionalAttributes->GetControlInformationElementL(category, i).Identifier();
       
  1480 
       
  1481 	    if (id == CSmsInformationElement::ESmsEnhanceVoiceMailInformation)
       
  1482 	        {
       
  1483 	        rc = ETrue;
       
  1484 	        break;
       
  1485 	        }
       
  1486 	    }
       
  1487 
       
  1488 	return rc;
       
  1489 	} // CSmsEnhancedVoiceMailOperations::ContainsEnhancedVoiceMailIEL
       
  1490 
       
  1491 
       
  1492 /**
       
  1493  *  Status Reporting.
       
  1494  *  
       
  1495  *  @note This should be the last thing that should be configured in CSmsMessage.
       
  1496  *  If anything is changed after this then the number of PDUs might change which
       
  1497  *  will affect status reporting.
       
  1498  */
       
  1499 CSmsEnhancedVoiceMailOperations::CSmsEnhancedVoiceMailOperations(CSmsInformationElement::TSmsInformationElementIdentifier aId,  CSmsMessage& aMessage,
       
  1500                                                                  CCnvCharacterSetConverter& aCharacterSetConverter, RFs& aFs) : CSmsCtrlOperation(aId, aMessage),
       
  1501                                                                  iCharacterSetConverter(aCharacterSetConverter), iFs(aFs)
       
  1502 	{
       
  1503 	// NOP
       
  1504 	} // CSmsEnhancedVoiceMailOperations::CSmsEnhancedVoiceMailOperations
       
  1505 
       
  1506 
       
  1507 CSmsSMSCCtrlParameterOperations::CSmsSMSCCtrlParameterOperations(CSmsInformationElement::TSmsInformationElementIdentifier aId, CSmsMessage& aMessage)
       
  1508 : CSmsCtrlOperation(aId, aMessage)
       
  1509 	{
       
  1510 	
       
  1511 	} // CSmsSMSCCtrlParameterOperations::CSmsSMSCCtrlParameterOperations
       
  1512 	
       
  1513 
       
  1514 /**
       
  1515  *  @internalComponent  
       
  1516  *  
       
  1517  *  Prevent clients from using the assignment operator by including it in the class definition
       
  1518  *  but making it protected and not exporting it.
       
  1519  *  
       
  1520  *  @capability None
       
  1521  */
       
  1522 void CSmsSMSCCtrlParameterOperations::operator=(const CSmsSMSCCtrlParameterOperations&)
       
  1523     {
       
  1524     // Ignore in code coverage - not intended to be used
       
  1525     BULLSEYE_OFF    
       
  1526     LOGGSMU1("CSmsSMSCCtrlParameterOperations::operator=");
       
  1527     Panic(KGsmuPanicMethodBodyNotImplemented1);
       
  1528     BULLSEYE_RESTORE
       
  1529     }
       
  1530 
       
  1531 /**
       
  1532  *  @internalComponent  
       
  1533  *  
       
  1534  *  Prevent clients from using the equality operator by including it in the class definition
       
  1535  *  but making it protected and not exporting it.
       
  1536  *  
       
  1537  *  @capability None
       
  1538  */
       
  1539 TBool CSmsSMSCCtrlParameterOperations::operator==(const CSmsSMSCCtrlParameterOperations&)
       
  1540     {
       
  1541     // Ignore in code coverage - not intended to be used
       
  1542     BULLSEYE_OFF    
       
  1543     LOGGSMU1("CSmsSMSCCtrlParameterOperations::operator==");
       
  1544     Panic(KGsmuPanicMethodBodyNotImplemented1);
       
  1545     return EFalse;
       
  1546     BULLSEYE_RESTORE
       
  1547     }
       
  1548 
       
  1549 /**
       
  1550  *  @internalComponent
       
  1551  *  
       
  1552  *  Identifies whether the message type or version supports this operation
       
  1553  *  
       
  1554  *  @leave
       
  1555  *  If the message type or version does not support this operation.
       
  1556  */
       
  1557 void CSmsSMSCCtrlParameterOperations::ValidateOperationL() const
       
  1558 	{
       
  1559 	if (iMessage.Version() < CSmsMessage::ESmsMessageV2)
       
  1560 	    {
       
  1561 	    LOGGSMU2("CSmsSMSCCtrlParameterOperations Operation not supported, Msg Version %d", iMessage.Version());
       
  1562 	    User::Leave(KErrNotSupported); 
       
  1563 	    }
       
  1564 
       
  1565 	if (!MessageTypeSupported())
       
  1566 	    {
       
  1567 	    LOGGSMU2("CSmsSMSCCtrlParameterOperations Operation not supported by this PDU type, type = %d", iMessage.Type());
       
  1568 	    User::Leave(KErrNotSupported);
       
  1569 	    }
       
  1570 	} // CSmsSMSCCtrlParameterOperations::ValidateOperationL()
       
  1571 
       
  1572 
       
  1573 /**
       
  1574  *  @internalComponent
       
  1575  *  
       
  1576  *  Checks that the octet passed to it has the valid bits set in it. If the bits which 
       
  1577  *  are not supported yet are set then reset it. 
       
  1578  *  This method is called by SetStatusReportL.
       
  1579  *  
       
  1580  *  @param aSelectiveStatus
       
  1581  *  The octet which needs to be set as the Selective Status for the report.
       
  1582  *  @return
       
  1583  *  ETrue if the selective status is valid.
       
  1584  *  @leave KErrNotSupported
       
  1585  *  If the last 4 bits are set as they are not supported.
       
  1586  */
       
  1587 TBool CSmsSMSCCtrlParameterOperations::ValidateControlParametersL(TUint8& aSelectiveStatus) const
       
  1588 	{
       
  1589 	if (aSelectiveStatus & ESmsStatusReportForFutureUse1)
       
  1590 		{
       
  1591 		User::Leave(KErrNotSupported);
       
  1592 		}
       
  1593 		
       
  1594 	if (aSelectiveStatus & ESmsStatusReportForFutureUse2)
       
  1595 		{
       
  1596 		User::Leave(KErrNotSupported);	
       
  1597 		}
       
  1598 		
       
  1599 	if (aSelectiveStatus & ESmsStatusReportCancelRestSRR)
       
  1600 		{
       
  1601 		User::Leave(KErrNotSupported);	
       
  1602 		}
       
  1603 		
       
  1604 	if (aSelectiveStatus & ESmsStatusReportIncludeOriginalUDH)
       
  1605 		{
       
  1606 		User::Leave(KErrNotSupported);
       
  1607 		}
       
  1608 	
       
  1609 	return ETrue;	
       
  1610 	} // CSmsSMSCCtrlParameterOperations::ValidateControlParametersL
       
  1611 
       
  1612 
       
  1613 /**
       
  1614  *  @publishedAll
       
  1615  *  
       
  1616  *  Sets the status report for a PDU. First the scheme is obtained by calling the 
       
  1617  *  GetStatusReportScheme and checked if it is the valid scheme. Then aSelectiveStatus is 
       
  1618  *  checked to see if it is the default value. If it is then nothing is done. But if 
       
  1619  *  aSelectiveStatus is non-default then it is appended to the array 
       
  1620  *  iControlParametersStatusReport along with the aSegmentSequenceNum 
       
  1621  *  
       
  1622  *  @param aSegmentSequenceNum
       
  1623  *  The segment sequence number of the PDU which needs to be updated.
       
  1624  *  @param aSelectiveStatus
       
  1625  *  The octet which needs to be set as the Selective Status for the report.
       
  1626  *  @return KErrNone if the operation is successful.
       
  1627  *  KErrNotFound if the Segment Sequence Number is out of range or the scheme is inavlid.
       
  1628  *  KErrNotSupported if aSelectiveStatus is not valid.
       
  1629  *  @leave
       
  1630  *  If ValidateOperationL or AppendL leaves.
       
  1631  *  @capability None
       
  1632  */
       
  1633 EXPORT_C TInt CSmsSMSCCtrlParameterOperations::SetStatusReportL(TUint aSegmentSequenceNum, TUint8 aSelectiveStatus)
       
  1634 	{
       
  1635 	ValidateOperationL();
       
  1636 	TBool validateStatus = ValidateControlParametersL(aSelectiveStatus);
       
  1637 	
       
  1638 	if(validateStatus)
       
  1639 		{
       
  1640 		CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
       
  1641 		CSmsMessageAdditionalAttributes::CSmsStatusReportScheme& scheme = additionalAttributes.GetStatusReportScheme();
       
  1642 		if (scheme.Id() == EControlParametersScheme)
       
  1643 			{
       
  1644 			CSmsMessageAdditionalAttributes::CControlParametersScheme& ctrlParamsScheme = (CSmsMessageAdditionalAttributes::CControlParametersScheme&)scheme;
       
  1645 			if(aSegmentSequenceNum>=ctrlParamsScheme.iNumOfPDUs)
       
  1646 				{
       
  1647 				return KErrNotFound;	//	aSegmentSequenceNum out of range.
       
  1648 				}
       
  1649 			if (aSelectiveStatus == ctrlParamsScheme.iDefaultStatusReport)
       
  1650 				{
       
  1651 				return KErrNone;	// It's the same as default so need for any updation.
       
  1652 				}
       
  1653 			else
       
  1654 				{
       
  1655 				TInt count = (ctrlParamsScheme.iControlParametersStatusReport).Count();
       
  1656 				TBool found(EFalse);
       
  1657 				for (TInt ii=0; !found && ii<count; ii++)
       
  1658 					{
       
  1659 					if ((ctrlParamsScheme.iControlParametersStatusReport[ii]).iSegmentSequenceNum == aSegmentSequenceNum)
       
  1660 						{
       
  1661 						(ctrlParamsScheme.iControlParametersStatusReport[ii]).iSelectiveStatus = aSelectiveStatus;
       
  1662 						found = ETrue;
       
  1663 						break;
       
  1664 						}
       
  1665 					}
       
  1666 					
       
  1667 				if (!found)
       
  1668 					{
       
  1669 					CSmsMessageAdditionalAttributes::CControlParametersScheme::TSmsSMSCCtrlParameterStatus smscCtrlParameterStatus;
       
  1670 					smscCtrlParameterStatus.iSegmentSequenceNum = aSegmentSequenceNum;
       
  1671 					smscCtrlParameterStatus.iSelectiveStatus = aSelectiveStatus;
       
  1672 					(ctrlParamsScheme.iControlParametersStatusReport).AppendL(smscCtrlParameterStatus);
       
  1673 					}
       
  1674 			
       
  1675 				return KErrNone;	
       
  1676 				}
       
  1677 			}
       
  1678 		else
       
  1679 			{
       
  1680 			return KErrNotFound;	//	Scheme not valid.
       
  1681 			}
       
  1682 		}
       
  1683 	else
       
  1684 		{
       
  1685 		return KErrNotSupported;	//	Invalid aSlectiveStatus.
       
  1686 		}
       
  1687 	} // CSmsSMSCCtrlParameterOperations::SetStatusReportL
       
  1688 
       
  1689 
       
  1690 /**
       
  1691  *  @publishedAll
       
  1692  *  
       
  1693  *  Gets the selective status for a PDU if the scheme is set to the Control
       
  1694  *  Parameters Scheme.
       
  1695  *  
       
  1696  *  @param aSegmentSequenceNum
       
  1697  *  The segment sequence number of the PDU whose status report is required.
       
  1698  *  @param aSelectiveStatus
       
  1699  *  Returns the selective status octet for that PDU.
       
  1700  *  
       
  1701  *  @return KErrNotFound if the segment sequence number or the scheme is invalid.
       
  1702  *  
       
  1703  *  @capability None
       
  1704  */
       
  1705 EXPORT_C TInt CSmsSMSCCtrlParameterOperations::GetStatusReport(TUint aSegmentSequenceNum,
       
  1706 															   TUint8& aSelectiveStatus) const
       
  1707 	{
       
  1708 	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
       
  1709 	CSmsMessageAdditionalAttributes::CSmsStatusReportScheme& scheme = additionalAttributes->GetStatusReportScheme();
       
  1710 	if (scheme.Id() == EControlParametersScheme)
       
  1711 		{
       
  1712 		CSmsMessageAdditionalAttributes::CControlParametersScheme& ctrlParamsScheme = (CSmsMessageAdditionalAttributes::CControlParametersScheme&)scheme;
       
  1713 		
       
  1714 		if(aSegmentSequenceNum>=ctrlParamsScheme.iNumOfPDUs)
       
  1715 			{
       
  1716 			return KErrNotFound;	//	aSegmentSequenceNum out of range.
       
  1717 			}
       
  1718 
       
  1719 		TInt count = (ctrlParamsScheme.iControlParametersStatusReport).Count();
       
  1720 		
       
  1721 		for (TInt ii=0; ii<count; ii++)
       
  1722 			{
       
  1723 			if (ctrlParamsScheme.iControlParametersStatusReport[ii].iSegmentSequenceNum == aSegmentSequenceNum)
       
  1724 				{
       
  1725 				aSelectiveStatus = ctrlParamsScheme.iControlParametersStatusReport[ii].iSelectiveStatus;
       
  1726 				return KErrNone;
       
  1727 				}
       
  1728 			}
       
  1729 			
       
  1730 		aSelectiveStatus = ctrlParamsScheme.iDefaultStatusReport;
       
  1731 		return KErrNone;
       
  1732 		}
       
  1733 
       
  1734 	return KErrNotFound;
       
  1735 	} // CSmsSMSCCtrlParameterOperations::GetStatusReport
       
  1736 
       
  1737 
       
  1738 /**
       
  1739  *  @publishedAll
       
  1740  *  
       
  1741  *  Sets the default value of the status report to aDefaultSelectiveStatus.
       
  1742  *  
       
  1743  *  @param aDefaultSelectiveStatus
       
  1744  *  The selective status to be used as default.
       
  1745  *  @leave KErrNotFound
       
  1746  *  If the scheme is invalid.
       
  1747  *  @capability None
       
  1748  */
       
  1749 EXPORT_C void CSmsSMSCCtrlParameterOperations::SetDefaultL(TUint8 aDefaultSelectiveStatus)
       
  1750 	{
       
  1751 	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
       
  1752 	CSmsMessageAdditionalAttributes::CSmsStatusReportScheme& scheme = additionalAttributes.GetStatusReportScheme();
       
  1753 	if (scheme.Id() == EControlParametersScheme)
       
  1754 		{
       
  1755 		CSmsMessageAdditionalAttributes::CControlParametersScheme& ctrlParamsScheme = (CSmsMessageAdditionalAttributes::CControlParametersScheme&)scheme;
       
  1756 		if(aDefaultSelectiveStatus & ESmsSMSCControlParametersMask)
       
  1757 			{
       
  1758 			ctrlParamsScheme.iDefaultStatusReport = aDefaultSelectiveStatus;
       
  1759 			}
       
  1760 		else
       
  1761 			{
       
  1762 			ctrlParamsScheme.iDefaultStatusReport = 0x00;	
       
  1763 			}
       
  1764 		}
       
  1765 	else
       
  1766 		{
       
  1767 		User::Leave(KErrNotFound);
       
  1768 		}
       
  1769 	} // CSmsSMSCCtrlParameterOperations::SetDefaultL
       
  1770 
       
  1771 
       
  1772 /**
       
  1773  *  @publishedAll
       
  1774  *  
       
  1775  *  This method is called to set the scheme to Control Parameters Scheme.
       
  1776  *  First iStatusReportScheme, which is obtained by calling GetStatusReportScheme,
       
  1777  *  is deleted and set to NULL. Then a new scheme is created and a default value is set.
       
  1778  *  This should be the last method to be called in a message sending process as all the 
       
  1779  *  operations in this interface depend on the number of PDUs being set.
       
  1780  *  
       
  1781  *  @leave
       
  1782  *  If ValidateOperationL or NumMessagePDUsL leaves.
       
  1783  *  @capability None
       
  1784  */
       
  1785 EXPORT_C void CSmsSMSCCtrlParameterOperations::SetSchemeL()
       
  1786 	{
       
  1787 	ValidateOperationL();
       
  1788 	
       
  1789 	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
       
  1790 	additionalAttributes.SetStatusReportSchemeL(EControlParametersScheme);
       
  1791 	
       
  1792 	TBuf8 <1> buffer;
       
  1793 	buffer.SetLength(1);
       
  1794 	buffer[0] = 0;
       
  1795 	
       
  1796 	CSmsUserData& userData = iMessage.SmsPDU().UserData();
       
  1797 
       
  1798 	userData.AddInformationElementL(CSmsInformationElement::ESmsIEISMSCControlParameters,buffer);
       
  1799 	
       
  1800 	CSmsMessageAdditionalAttributes::CSmsStatusReportScheme& scheme = additionalAttributes.GetStatusReportScheme();
       
  1801 	CSmsMessageAdditionalAttributes::CControlParametersScheme& ctrlParamsScheme = (CSmsMessageAdditionalAttributes::CControlParametersScheme&)scheme;
       
  1802 	ctrlParamsScheme.iNumOfPDUs = iMessage.NumMessagePDUsL();
       
  1803 
       
  1804 	SetDefaultL(0);
       
  1805 	} // CSmsSMSCCtrlParameterOperations::SetSchemeL
       
  1806 
       
  1807 
       
  1808 /**
       
  1809  *  @publishedAll
       
  1810  *  
       
  1811  *  Gets the current scheme being used.
       
  1812  *  
       
  1813  *  @return
       
  1814  *  EControlParametrsScheme is returned when Control Parameters Scheme is being used.
       
  1815  *  @capability None
       
  1816  */
       
  1817 EXPORT_C TSmsStatusReportScheme CSmsSMSCCtrlParameterOperations::GetScheme() const
       
  1818 	{
       
  1819 	CSmsMessageAdditionalAttributes* additionalAttributes = (CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo();
       
  1820 		
       
  1821 	return (additionalAttributes->GetStatusReportScheme()).Id();
       
  1822 	} // CSmsSMSCCtrlParameterOperations::GetScheme
       
  1823 
       
  1824 
       
  1825 /**
       
  1826  *  @publishedAll
       
  1827  *  
       
  1828  *  This method re-sets the scheme to the Default Scheme.
       
  1829  *  
       
  1830  *  @capability None
       
  1831  */
       
  1832 EXPORT_C void CSmsSMSCCtrlParameterOperations::ResetSchemeL()
       
  1833 	{
       
  1834 	CSmsMessageAdditionalAttributes& additionalAttributes = *((CSmsMessageAdditionalAttributes*) iMessage.AdditionalInfo());
       
  1835 	
       
  1836 	CSmsUserData& userData = iMessage.SmsPDU().UserData();
       
  1837 
       
  1838 	CArrayFixFlat<TInt>* indices = new (ELeave) CArrayFixFlat<TInt>(8);
       
  1839 	CleanupStack::PushL(indices);
       
  1840 	userData.InformationElementIndicesL(CSmsInformationElement::ESmsIEISMSCControlParameters,*indices);
       
  1841 
       
  1842 	TUint i = indices->Count();
       
  1843 
       
  1844 	while (i-- != 0)
       
  1845 	    {
       
  1846 	    userData.RemoveInformationElement((*indices)[i]);
       
  1847 	    }
       
  1848     
       
  1849     CleanupStack::PopAndDestroy(indices);
       
  1850     additionalAttributes.SetStatusReportSchemeL(EDefaultScheme);
       
  1851 	} // CSmsSMSCCtrlParameterOperations::ResetSchemeL
       
  1852