diff -r 000000000000 -r ff3b6d0fd310 telutils/phoneparser/src/CPhoneGsmSsParser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/telutils/phoneparser/src/CPhoneGsmSsParser.cpp Tue Feb 02 01:11:09 2010 +0200 @@ -0,0 +1,1387 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Principal parser for supplementary service procedures. +* +*/ + + +// INCLUDE FILES +#include +#include +#include + +#include "CPhoneGsmSsParser.h" +#include "CPhoneGsmParserResult.h" +#include "PhoneGsmParser.h" +#include "CPhoneGsmOptionContainer.h" +#include "CPhoneParserFeatures.h" + +// CONSTANTS + +// Granularity of service array +const TInt KPhoneServiceArrayGranularity = 20; + +// Activation starts with *. See also registration. +_LIT( KPhoneSsActivation, "*" ); + +// Deactivation starts with #. +_LIT( KPhoneSsDeactivation, "#" ); + +// Interrogation starts with *#. +_LIT( KPhoneSsInterrogation, "*#" ); + +// Registration starts with ** OR *. Case * is handled in the code. +_LIT( KPhoneSsRegistration, "**" ); + +// Erasure starts with ##. +_LIT( KPhoneSsErasure, "##" ); + +// It defines characters that can be used in these prefixes (see above). +_LIT( KPhoneSsActionCharacters, "*#" ); + +// It defines string that ends all ss requests. +_LIT( KPhoneSsEnd, "#" ); + +// It defines characters that are considered to be digits. +_LIT( KPhoneSsDigits, "1234567890" ); + +// Asterisk. +const TInt KPhoneSsAsterisk = '*'; + +// Hash. +const TInt KPhoneSsHash = '#'; + +// Plus. +const TInt KPhoneSsPlus = '+'; + +// Remainder: single character +const TInt KPhoneSsRemainderSingle = 1; + +// Remainder: still a parameter, but ok ss +const TInt KPhoneSsRemainderMinLength = 2; // something + # + +const TInt KPhoneSsPasswordLength = 4; + +// Remainder: passwordk, ok ss +const TInt KPhoneSsRemainderPasswordMinLength = 5; // four digits + # + +// Maximum length of directory number. +const TInt KPhoneSsDirectoryNumberMaxLength = 38; +// Maximum length of basic service code. +const TInt KPhoneSsBasicCodeMaxLength = 2; +// Maximum length of group code. +const TInt KPhoneSsGroupCodeMaxLength = 4; +// Maximum length of timer. +const TInt KPhoneSsTimerMaxLength = 2; + +// The only acceptable group code (change of barring password) +const TUint KPhoneSsOnlyAllowedGroupCode = 330; + +// Pack: shift +const TInt KPhoneGsmPackShift = 8; + +// Pack: mask +const TInt KPhoneGsmPackMask = 255; + +// ----------------------------------------------------------------------------- +// Syntax: +// +// SC Service code +// A Activation +// D Deactivation +// I Interrogation +// R Registration +// E Erasure +// +// Text string must contain each of these in the following order +// "SC A D I R E" (separated by space). Following values correspond +// +// +// 0 - ENotAllowed +// 1 - ENoParameters +// 2 - EEmptyOrBasicCode +// 3 - ENumberOptBasicCodeOptTimer +// 4 - ENumberOptBasicCode +// 5 - EPasswordOptBasicCode +// 6 - EOptGroupCodePasswordNewPasswordNewPassword +// 7 - EEmptyOrBasicCode2 +// ----------------------------------------------------------------------------- +_LIT( KPhoneUidForwardingAllCode, "002 2 2 0 3 2" ); +_LIT( KPhoneUidForwardingAllConditionalCode, "004 2 2 0 3 2" ); +_LIT( KPhoneUidForwardingUnconditionalCode, "21 2 2 2 4 2" ); +_LIT( KPhoneUidForwardingNoReplyCode, "61 2 2 2 3 2" ); +_LIT( KPhoneUidForwardingNotReachableCode, "62 2 2 2 4 2" ); +_LIT( KPhoneUidForwardingBusyCode, "67 2 2 2 4 2" ); +_LIT( KPhoneUidBarringAllOutgoingCallsCode, "33 5 5 1 0 0" ); +_LIT( KPhoneUidBarringAllIncomingCallsCode, "35 5 5 1 0 0" ); +_LIT( KPhoneUidBarringAllServicesCode, "330 0 5 0 0 0" ); +_LIT( KPhoneUidBarringAllOutgoingInternationalCallsCode, "331 5 5 1 0 0" ); +_LIT( KPhoneUidBarringAllOutgoingInternationalCallsExceptHomeCode, "332 5 5 1 0 0" ); +_LIT( KPhoneUidBarringAllOutgoingServicesCode, "333 0 5 0 0 0" ); +_LIT( KPhoneUidBarringAllIncomingCallsWhenRoamingCode, "351 5 5 1 0 0" ); +_LIT( KPhoneUidBarringAllIncomingServicesCode, "353 0 5 0 0 0" ); +_LIT( KPhoneUidWaitingCode, "43 7 7 7 0 0" ); +_LIT( KPhoneUidCallingLineIdentificationPresentationCode, "30 0 0 1 0 0" ); +_LIT( KPhoneUidCallingLineIdentificationRestrictionCode, "31 0 0 1 0 0" ); +_LIT( KPhoneUidConnectedLinePresentationCode, "76 0 0 1 0 0" ); +_LIT( KPhoneUidConnectedLinePresentationRestrictionCode, "77 0 0 1 0 0" ); +_LIT( KPhoneUidPasswordCode, "03 6 0 0 6 0" ); +_LIT( KPhoneUidCallingNamePresentationCode, "300 0 0 1 0 0" ); + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::CPhoneGsmSsParser +// ----------------------------------------------------------------------------- +// +CPhoneGsmSsParser::CPhoneGsmSsParser() + { + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::ConstructL +// ----------------------------------------------------------------------------- +// +void CPhoneGsmSsParser::ConstructL() + { + iArray = + new ( ELeave ) CServiceArray( + KPhoneServiceArrayGranularity ); + + // Check AddL method for details what these really mean. + + // Forwarding + AddL( KPhoneUidForwardingAllCode, + KPhoneUidForwardingAll ); + AddL( KPhoneUidForwardingAllConditionalCode, + KPhoneUidForwardingAllConditional ); + AddL( KPhoneUidForwardingUnconditionalCode, + KPhoneUidForwardingUnconditional ); + AddL( KPhoneUidForwardingNoReplyCode, + KPhoneUidForwardingNoReply ); + AddL( KPhoneUidForwardingNotReachableCode, + KPhoneUidForwardingNotReachable ); + AddL( KPhoneUidForwardingBusyCode, + KPhoneUidForwardingBusy ); + + // Barring + AddL( KPhoneUidBarringAllOutgoingCallsCode, + KPhoneUidBarringAllOutgoingCalls ); + AddL( KPhoneUidBarringAllIncomingCallsCode, + KPhoneUidBarringAllIncomingCalls ); + AddL( KPhoneUidBarringAllServicesCode, + KPhoneUidBarringAllServices ); + AddL( KPhoneUidBarringAllOutgoingInternationalCallsCode, + KPhoneUidBarringAllOutgoingInternationalCalls ); + AddL( KPhoneUidBarringAllOutgoingInternationalCallsExceptHomeCode, + KPhoneUidBarringAllOutgoingInternationalCallsExceptHome ); + AddL( KPhoneUidBarringAllOutgoingServicesCode, + KPhoneUidBarringAllOutgoingServices ); + AddL( KPhoneUidBarringAllIncomingCallsWhenRoamingCode, + KPhoneUidBarringAllIncomingCallsWhenRoaming ); + AddL( KPhoneUidBarringAllIncomingServicesCode, + KPhoneUidBarringAllIncomingServices ); + + // Waiting + AddL( KPhoneUidWaitingCode, + KPhoneUidWaiting ); + + // Calling line identification presentation + AddL( KPhoneUidCallingLineIdentificationPresentationCode, + KPhoneUidCallingLineIdentificationPresentation ); + + // Calling line identification restriction + AddL( KPhoneUidCallingLineIdentificationRestrictionCode, + KPhoneUidCallingLineIdentificationRestriction ); + + // Connected line presentation + AddL( KPhoneUidConnectedLinePresentationCode, + KPhoneUidConnectedLinePresentation ); + + // Connected line presentation restriction. + AddL( KPhoneUidConnectedLinePresentationRestrictionCode, + KPhoneUidConnectedLinePresentationRestriction ); + + // CNAP. + if ( CPhoneParserFeatures::FeatureSupported( KFeatureIdPhoneCnap ) ) + { + AddL( KPhoneUidCallingNamePresentationCode, + KPhoneUidCallingNamePresentation ); + } + + // Password + AddL( KPhoneUidPasswordCode, + KPhoneUidPassword ); + + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::NewLC +// ----------------------------------------------------------------------------- +// +CPhoneGsmSsParser* CPhoneGsmSsParser::NewLC() + { + CPhoneGsmSsParser* self = new ( ELeave ) CPhoneGsmSsParser; + + CleanupStack::PushL( self ); + self->ConstructL(); + + return self; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::~CPhoneGsmSsParser +// ----------------------------------------------------------------------------- +// +CPhoneGsmSsParser::~CPhoneGsmSsParser() + { + delete iArray; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::ParseL +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::ParseL( + const TDesC& aString, + CPhoneGsmParserResult& aResult, + CPhoneGsmOptionContainerBase& aOptions ) + { + TBool result = EFalse; + aResult.ClearL(); +// All operations require SEND. +// If VoIP call no action needed here. + if ( !aOptions.FindOptionStatus( KPhoneOptionSend ) || + aOptions.FindOptionStatus( KPhoneOptionVoipCall ) ) + { + return EFalse; + } + + TLex input( aString ); + TPtrC action( + FindString( + input, + KPhoneSsActionCharacters() ) ); + + // Check if action is proper for service requests. + TServiceType type = EServiceActivation; + + // This variable will indicate if action was ok. + TBool ok = ETrue; + + // Fill type. + if ( action == KPhoneSsActivation ) + { + type = EServiceActivation; + } + else if ( action == KPhoneSsDeactivation ) + { + type = EServiceDeactivation; + } + else if ( action == KPhoneSsInterrogation ) + { + type = EServiceInterrogation; + } + else if ( action == KPhoneSsRegistration ) + { + type = EServiceRegistration; + } + else if ( action == KPhoneSsErasure ) + { + type = EServiceErasure; + } + else + { + // Not ok. + ok = EFalse; + } + + // Prefix must be one of the service types. + if ( ok ) + { + TPtrC serviceCode( FindString( input, KPhoneSsDigits() ) ); + + // Check that service code is not too long. + if ( serviceCode.Length() > KPhoneGsmSsServiceCodeMaxLength ) + { + return EFalse; + } + + TKeyArrayFix key( _FOFF( TServiceInfo, iCode ), ECmpNormal ); + TServiceInfo info; + TInt position; + info.iCode = serviceCode; + + // Check if the string can be a service request. + if ( !iArray->FindIsq( info, key, position ) ) + { + info = iArray->At( position ); + } + else + { + // Not found. + return EFalse; + } + + TServiceSyntax syntax = ESyntaxNotAllowed; + + // Take syntax from info record. + switch ( type ) + { + case EServiceActivation: + syntax = info.iActivation; + break; + + case EServiceDeactivation: + syntax = info.iDeactivation; + break; + + case EServiceInterrogation: + syntax = info.iInterrogation; + break; + + case EServiceRegistration: + syntax = info.iRegistration; + break; + + case EServiceErasure: + syntax = info.iErasure; + break; + + default: + PhoneGsmParser::Panic( PhoneGsmParser::EShouldNeverHappen ); + break; + } + + TUint data; + PackData( data, type, syntax ); + + aResult.SetUid( info.iUid ); + aResult.SetAuxInformation( data ); + + // We may have to backtrack in case HandleParametersL fails. + TLexMark mark; + input.Mark( mark ); + + // First attempt + result = HandleParametersL( input, aResult, syntax ); + + // If action was activation and result was failure, then try registration. + if ( !result && type == EServiceActivation ) + { + // Backtrack. + input.UnGetToMark( mark ); + + // Clear previous results & fill information again. + + type = EServiceRegistration; + syntax = info.iRegistration; + PackData( data, type, syntax ); + + aResult.ClearL(); + aResult.SetUid( info.iUid ); + aResult.SetAuxInformation( data ); + + // Try again. If this fails, then it is really failure. + result = HandleParametersL( input, aResult, syntax ); + } + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::PackData +// +// Combine data to integer. +// ----------------------------------------------------------------------------- +// +void CPhoneGsmSsParser::PackData( + TUint& aResult, + TServiceType aType, + TServiceSyntax aSyntax ) + { + aResult = + ( ( ( TUint )aType ) << KPhoneGsmPackShift ) + ( ( TUint )aSyntax ); + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::UnpackData +// +// Take data from integer. +// ----------------------------------------------------------------------------- +// +void CPhoneGsmSsParser::UnpackData( + TUint aData, + TServiceType& aResultType, + TServiceSyntax& aResultSyntax ) + { + aResultSyntax = + CPhoneGsmSsParser::TServiceSyntax( aData & KPhoneGsmPackMask ); + aResultType = + CPhoneGsmSsParser::TServiceType( + ( aData >> KPhoneGsmPackShift ) & + KPhoneGsmPackMask ); + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::HandleParametersL +// +// Selects correct function by syntax information. +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::HandleParametersL( + TLex& aInput, + CPhoneGsmParserResult& aResult, + TServiceSyntax aSyntax ) + { + TBool result = EFalse; + + switch ( aSyntax ) + { + case ESyntaxNotAllowed: + result = + HandleNotAllowedL( aInput, aResult ); + break; + + case ESyntaxNoParameters: + result = + HandleNoParametersL( aInput, aResult ); + break; + + case ESyntaxEmptyOrBasicCode: + result = + HandleEmptyOrBasicCodeL( aInput, aResult ); + break; + + case ESyntaxNumberOptBasicCodeOptTimer: + result = + HandleNumberOptBasicCodeOptTimerL( + aInput, + aResult ); + break; + + case ESyntaxNumberOptBasicCode: + result = + HandleNumberOptBasicCodeL( + aInput, + aResult ); + break; + + case ESyntaxPasswordOptBasicCode: + result = + HandlePasswordOptBasicCodeL( + aInput, + aResult ); + break; + + case ESyntaxOptGroupCodePasswordNewPasswordNewPassword: + result = + HandleOptGroupCodePasswordNewPasswordNewPasswordL( + aInput, + aResult ); + break; + + case ESyntaxEmptyOrBasicCode2: + result = + HandleEmptyOrBasicCode2L( + aInput, + aResult ); + break; + + default: + break; + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::HandleNotAllowedL +// +// Just clear the result and return that parsing failed. +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::HandleNotAllowedL( + TLex& /*aInput*/, + CPhoneGsmParserResult& aResult ) + { + aResult.ClearL(); + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::HandleNoParametersL +// +// Handle no more parameters, only hash +// as the last character. +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::HandleNoParametersL( + TLex& aInput, + CPhoneGsmParserResult& /*aResult*/ ) + { + // Next character is last character and it is hash character. + TBool result = EFalse; + TPtrC ptr = aInput.Remainder(); + + if ( ptr.Length() == KPhoneSsRemainderSingle ) + { + result = ( ptr[0] == KPhoneSsHash ); + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::HandleEmptyOrBasicCodeL +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::HandleEmptyOrBasicCodeL( + TLex& aInput, + CPhoneGsmParserResult& aResult ) + { + TBool result = EFalse; + + if ( HandleNoParametersL( aInput, aResult ) ) + { + aResult.AddParameterL( KNullDesC ); + aResult.AddParameterL( KNullDesC ); + result = ETrue; + } + else + { + result = HandleEmptyParameterL( aInput, aResult ); + + if ( result ) + { + result = HandleBasicCodeL( aInput, aResult ); + result = result && HandleNoParametersL( aInput, aResult ); + } + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::HandleNumberOptBasicCodeOptTimerL +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::HandleNumberOptBasicCodeOptTimerL( + TLex& aInput, + CPhoneGsmParserResult& aResult ) + { + TBool result = EFalse; + + if ( HandleNumberL( aInput, aResult ) ) + { + if ( HandleNoParametersL( aInput, aResult ) ) + { + // Add basic code and timer. + aResult.AddParameterL( KNullDesC ); + aResult.AddParameterL( KNullDesC ); + result = ETrue; + } + else + { + if ( HandleBasicCodeL( aInput, aResult ) ) + { + if ( HandleTimerL( aInput, aResult ) ) + { + result = HandleNoParametersL( aInput, aResult ); + } + else + { + result = HandleNoParametersL( aInput, aResult ); + aResult.AddParameterL( KNullDesC ); + } + } + else if ( HandleEmptyParameterL( aInput, aResult ) ) + { + result = HandleTimerL( aInput, aResult ); + result = result && + HandleNoParametersL( aInput, aResult ); + } + } + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::HandleNumberOptBasicCodeL +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::HandleNumberOptBasicCodeL( + TLex& aInput, + CPhoneGsmParserResult& aResult ) + { + TBool result = EFalse; + + if ( HandleNumberL( aInput, aResult ) ) + { + if ( HandleNoParametersL( aInput, aResult ) ) + { + aResult.AddParameterL( KNullDesC ); + result = ETrue; + } + else + { + result = HandleBasicCodeL( aInput, aResult ); + result = result && HandleNoParametersL( aInput, aResult ); + } + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::HandlePasswordOptBasicCodeL +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::HandlePasswordOptBasicCodeL( + TLex& aInput, + CPhoneGsmParserResult& aResult ) + { + TBool result = EFalse; + + if ( HandlePasswordL( aInput, aResult ) ) + { + if ( HandleNoParametersL( aInput, aResult ) ) + { + aResult.AddParameterL( KNullDesC ); + result = ETrue; + } + else + { + result = HandleBasicCodeL( aInput, aResult ); + result = result && HandleNoParametersL( aInput, aResult ); + } + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser:: +// HandleOptGroupCodePasswordNewPasswordNewPasswordL +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser:: + HandleOptGroupCodePasswordNewPasswordNewPasswordL( + TLex& aInput, + CPhoneGsmParserResult& aResult ) + { + TBool result = HandleGroupCodeL( aInput, aResult ); + + if ( !result ) + { + result = HandleEmptyParameterL( aInput, aResult ); + } + + result = result && HandlePasswordL( aInput, aResult ); + result = result && HandlePasswordL( aInput, aResult ); + result = result && HandlePasswordL( aInput, aResult ); + result = result && HandleNoParametersL( aInput, aResult ); + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::HandleEmptyOrBasicCode2L +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::HandleEmptyOrBasicCode2L( + TLex& aInput, + CPhoneGsmParserResult& aResult ) + { + TBool result = HandleNoParametersL( aInput, aResult ); + + if ( result ) + { + aResult.AddParameterL( KNullDesC ); + } + else + { + result = HandleBasicCodeL( aInput, aResult ); + result = result && HandleNoParametersL( aInput, aResult ); + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::HandleEmptyParameterL +// +// Handle empty parameter, two consecutive asterisks. +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::HandleEmptyParameterL( + TLex& aInput, + CPhoneGsmParserResult& aResult ) + { + TBool result = EFalse; + aInput.Mark(); + + if ( aInput.Peek() == KPhoneSsAsterisk ) + { + aInput.Inc(); + + result = ( aInput.Peek() == KPhoneSsAsterisk ); + + if ( result ) + { + aResult.AddParameterL( KNullDesC ); + } + } + + if ( !result ) + { + aInput.UnGetToMark(); + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::HandleBasicCodeL +// +// Basically, basic service code is a two digit string. +// In this method, only explicit +// values are handled (parameter might be empty). +// +// The method checks that the first character is * and then +// it is followed by two digits. And there must not be more +// than two digits. +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::HandleBasicCodeL( + TLex& aInput, + CPhoneGsmParserResult& aResult ) + { + TBool result = EFalse; + TLexMark start; + + aInput.Mark( start ); + + if ( aInput.Peek() == KPhoneSsAsterisk ) + { + aInput.Inc(); + + TLexMark mark; + aInput.Mark( mark ); + + if ( aInput.Peek().IsDigit() ) + { + aInput.Inc(); + + if ( aInput.Peek().IsDigit() ) + { + aInput.Inc(); + + if ( !aInput.Peek().IsDigit() ) + { + TPtrC code = aInput.MarkedToken( mark ); + + result = CheckBasicCode( code ); + + if ( result ) + { + aResult.AddParameterL( code ); + } + } + } + } + + // Check empty parameters. + if ( !result ) + { + aInput.UnGetToMark( mark ); + + if ( aInput.Remainder() == KPhoneSsEnd ) + { + aResult.AddParameterL( KNullDesC ); + result = ETrue; + } + } + } + + if ( !result ) + { + aInput.UnGetToMark( start ); + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::HandleNumberL +// +// Directory number as a parameter must be present. It can +// contain at most 38 digits. Digits and '+' characters +// are allowed, but '+' character is allowed to be only in the +// beginning of the string. +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::HandleNumberL( + TLex& aInput, + CPhoneGsmParserResult& aResult ) + { + if ( aInput.Remainder().Length() < KPhoneSsRemainderMinLength ) + { + return EFalse; + } + + TInt maxLength = KPhoneSsDirectoryNumberMaxLength; + TBool result = EFalse; + TLexMark start; + + aInput.Mark( start ); + + if ( aInput.Peek() == KPhoneSsAsterisk ) + { + aInput.Inc(); + + TLexMark mark; + aInput.Mark( mark ); + + if ( aInput.Peek() == KPhoneSsPlus ) + { + aInput.Inc(); + maxLength++; + } + + while ( aInput.Peek().IsDigit() ) + { + aInput.Inc(); + } + + TPtrC number = aInput.MarkedToken( mark ); + if ( number.Length() <= maxLength ) + { + aResult.AddParameterL( number ); + result = ETrue; + } + } + + if ( !result ) + { + aInput.UnGetToMark( start ); + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::HandleTimerL +// +// The method checks if the next part is 'no reply timer'. +// It is at most two digits. Value is expected to be present. +// Value is checked in CheckTimer method. +// +// (if value is not present, then it is handled in calling +// method) +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::HandleTimerL( + TLex& aInput, + CPhoneGsmParserResult& aResult ) + { + TBool result = EFalse; + TLexMark start; + aInput.Mark( start ); + + if ( aInput.Peek() == KPhoneSsAsterisk ) + { + aInput.Inc(); + + TLexMark mark; + aInput.Mark( mark ); + + while ( aInput.Peek().IsDigit() ) + { + aInput.Inc(); + } + + TPtrC timer( aInput.MarkedToken( mark ) ); + + if ( CheckTimer( timer ) ) + { + aResult.AddParameterL( timer ); + result = ETrue; + } + + // Check empty parameters. + if ( !result ) + { + aInput.UnGetToMark( mark ); + + if ( aInput.Remainder() == KPhoneSsEnd ) + { + aResult.AddParameterL( KNullDesC ); + result = ETrue; + } + } + } + + if ( !result ) + { + aInput.UnGetToMark( start ); + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::HandlePasswordL +// +// Password is four digit string. +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::HandlePasswordL( + TLex& aInput, + CPhoneGsmParserResult& aResult ) + { + if ( aInput.Remainder().Length() < + KPhoneSsRemainderPasswordMinLength ) + { + return EFalse; + } + + TBool result = EFalse; + TLexMark start; + aInput.Mark( start ); + + if ( aInput.Peek() == KPhoneSsAsterisk ) + { + aInput.Inc(); + + TLexMark mark; + aInput.Mark( mark ); + + while( aInput.Peek().IsDigit() ) + { + aInput.Inc(); + } + + TPtrC password( aInput.MarkedToken( mark ) ); + + if ( password.Length() == KPhoneSsPasswordLength ) + { + aResult.AddParameterL( password ); + result = ETrue; + } + } + + if ( !result ) + { + aInput.UnGetToMark( start ); + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::HandleGroupCodeL +// +// The method handles password group codes. However, code +// must be one to four digits. +// +// (if group code is null, then it is handled in calling +// method) +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::HandleGroupCodeL( + TLex& aInput, + CPhoneGsmParserResult& aResult ) + { + if ( aInput.Remainder().Length() <= KPhoneSsRemainderMinLength ) + { + return EFalse; + } + + TBool result = EFalse; + TLexMark start; + + aInput.Mark( start ); + + if ( aInput.Peek() == KPhoneSsAsterisk ) + { + aInput.Inc(); + + TLexMark mark; + aInput.Mark( mark ); + + while ( aInput.Peek().IsDigit() ) + { + aInput.Inc(); + } + + TPtrC groupCode( aInput.MarkedToken( mark ) ); + + if ( CheckGroupCode( groupCode ) ) + { + aResult.AddParameterL( groupCode ); + result = ETrue; + } + } + + if ( !result ) + { + aInput.UnGetToMark( start ); + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::CheckBasicCode +// +// Check that basic code is appropriate +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::CheckBasicCode( const TDesC& aCode ) + { + TLex lex( aCode ); + TUint value; + + if ( aCode.Length() <= KPhoneSsBasicCodeMaxLength ) + { + if ( lex.Val( value, EDecimal ) != KErrNone ) + { + return EFalse; + } + } + else + { + return EFalse; + } + + TBool result = EFalse; + + switch ( value ) + { + // TELESERVICES + case EAllTele: // GSM: All tele and bearer services + case ETelephony: // GSM: Teleservices + case EAllDataTele: // GSM: All data teleservices + case EFax: // GSM: Facsimile services + case ESms: // GSM: Short message services + case EAllTeleExcSms: // GSM: All teleservices except SMS + case EAltTele: // PCN: Alternate line service + + // BEARER SERVICES + case EAllBearer: // GSM: All bearer services + case EAllAsync: // GSM: All async services + case EAllSync: // GSM: All sync services + case ESyncData: // GSM: All data circuit sync + case EAsyncData: // GSM: All data circuit async + case EPacketData: // GSM: All dedicated packet access + case EPadAccess: // GSM: All dedicated PAD access + + result = ETrue; + break; + + // PLMN specific teleservices and bearer services + default: + + // GSM: PLMN specific teleservices + if ( value >= EAllPlmnTele && value <= EPlmnTeleF ) + { + result = ETrue; + } + // GSM: PLMN specific bearer services + else if ( value >= EAllPlmnBearer && value <= EPlmnBearerServF ) + { + result = ETrue; + } + + // Otherwise, result == EFalse and it's OK. + break; + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::CheckTimer +// +// Check if timer value is ok. +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::CheckTimer( const TDesC& aCode ) + { + TLex lex( aCode ); + TUint value; + + if ( aCode.Length() <= KPhoneSsTimerMaxLength ) + { + if ( lex.Val( value, EDecimal ) != KErrNone ) + { + return EFalse; + } + } + else + { + return EFalse; + } + + TBool result = EFalse; + + switch ( value ) + { + case 5: + case 10: + case 15: + case 20: + case 25: + case 30: + result = ETrue; + break; + + default: + break; + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::CheckGroupCode +// +// Check if group code is ok. +// ----------------------------------------------------------------------------- +// +TBool CPhoneGsmSsParser::CheckGroupCode( const TDesC& aCode ) + { + TLex lex( aCode ); + TUint value; + TBool result = EFalse; + + if ( aCode.Length() <= KPhoneSsGroupCodeMaxLength ) + { + if ( lex.Val( value, EDecimal ) == KErrNone ) + { + result = ( value == KPhoneSsOnlyAllowedGroupCode ); + } + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::FindString +// ----------------------------------------------------------------------------- +// +TPtrC CPhoneGsmSsParser::FindString( + TLex& aInput, + const TDesC& aAllowedCharacters ) + { + TLexMark mark; + aInput.Mark( mark ); + + // Return string containing characters that appear in + // aAllowedCharacters. + while ( aAllowedCharacters.Locate( aInput.Peek() ) != + KErrNotFound ) + { + aInput.Inc(); + } + + return aInput.MarkedToken( mark ); + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::AddL +// +// Parse service description and add it. +// +// ----------------------------------------------------------------------------- +// +void CPhoneGsmSsParser::AddL( + const TDesC& aService, + TUint aUid ) + { + // There must be six positive integers in aService. + TLex input( aService ); + + // First number is service code. + TPtrC serviceCode( NextNumber( input ) ); + + // And then next five are syntax descriptions. + TServiceSyntax activation = + ConvertToServiceSyntax( NextNumberAsValue( input ) ); + TServiceSyntax deactivation = + ConvertToServiceSyntax( NextNumberAsValue( input ) ); + TServiceSyntax interrogation = + ConvertToServiceSyntax( NextNumberAsValue( input ) ); + TServiceSyntax registration = + ConvertToServiceSyntax( NextNumberAsValue( input ) ); + TServiceSyntax erasure = + ConvertToServiceSyntax( NextNumberAsValue( input ) ); + + // Add to array. + AddServiceL( + serviceCode, + activation, + deactivation, + interrogation, + registration, + erasure, + aUid ); + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::AddServiceL +// ----------------------------------------------------------------------------- +// +void CPhoneGsmSsParser::AddServiceL( + const TDesC& aServiceCode, + TServiceSyntax aActivation, + TServiceSyntax aDeactivation, + TServiceSyntax aInterrogation, + TServiceSyntax aRegistration, + TServiceSyntax aErasure, + TUint aUid ) + { + TServiceInfo info; + + // Fill information to info structure. + info.iCode = aServiceCode; + info.iActivation = aActivation; + info.iDeactivation = aDeactivation; + info.iInterrogation = aInterrogation; + info.iRegistration = aRegistration; + info.iErasure = aErasure; + info.iUid = aUid; + + TKeyArrayFix key( _FOFF( TServiceInfo, iCode ), ECmpNormal ); + + // Add it to the array. + TRAPD( err, iArray->InsertIsqL( info, key ) ); + + if ( err != KErrNone && err != KErrNoMemory ) + { + PhoneGsmParser::Panic( + PhoneGsmParser::EIncorrectServiceDescription ); + } + + // Just leave if no memory. + if ( err == KErrNoMemory ) + { + User::Leave( err ); + } + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::NextNumber +// +// Skip spaces and then get next number. +// ----------------------------------------------------------------------------- +// +TPtrC CPhoneGsmSsParser::NextNumber( + TLex& aLex ) + { + // Skip whites. + aLex.SkipSpace(); + + // Go over digits. + aLex.Mark(); + while ( aLex.Peek().IsDigit() ) + { + aLex.Inc(); + } + + // Check if we got proper number. + if ( !aLex.TokenLength() ) + { + PhoneGsmParser::Panic( + PhoneGsmParser::EIncorrectServiceDescription ); + } + + return aLex.MarkedToken(); + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::NextNumberAsValue +// +// Get number and convert it to value. +// ----------------------------------------------------------------------------- +// +TUint CPhoneGsmSsParser::NextNumberAsValue( + TLex& aLex ) + { + // Get number. + TPtrC number( NextNumber( aLex ) ); + TLex input( number ); + TUint value; + + // Parse number. + if ( input.Val( value, EDecimal ) != KErrNone ) + { + PhoneGsmParser::Panic( + PhoneGsmParser::EIncorrectServiceDescription ); + } + + return value; + } + +// ----------------------------------------------------------------------------- +// CPhoneGsmSsParser::ConvertToServiceSyntax +// +// Convert value to a service syntax enumeration. +// ----------------------------------------------------------------------------- +// +CPhoneGsmSsParser::TServiceSyntax + CPhoneGsmSsParser::ConvertToServiceSyntax( + TUint aService ) + { + TServiceSyntax service = ESyntaxNotAllowed; + + switch ( aService ) + { + case 0: + service = ESyntaxNotAllowed; + break; + case 1: + service = ESyntaxNoParameters; + break; + case 2: + service = ESyntaxEmptyOrBasicCode; + break; + case 3: + service = ESyntaxNumberOptBasicCodeOptTimer; + break; + case 4: + service = ESyntaxNumberOptBasicCode; + break; + case 5: + service = ESyntaxPasswordOptBasicCode; + break; + case 6: + service = ESyntaxOptGroupCodePasswordNewPasswordNewPassword; + break; + case 7: + service = ESyntaxEmptyOrBasicCode2; + break; + default: + PhoneGsmParser::Panic( + PhoneGsmParser::EIncorrectServiceDescription ); + } + + return service; + } + +// End of File