cbs/CbsServer/ServerSrc/CCbsReceiverHelper.cpp
changeset 46 2fa1fa551b0b
parent 42 35488577e233
child 48 78df25012fda
equal deleted inserted replaced
42:35488577e233 46:2fa1fa551b0b
     1 /*
       
     2 * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This module contains the implementation of CCbsReceiverHelper class
       
    15 *                member functions.
       
    16 *
       
    17 *                CCbsReceiverHelper gets the messages from the receiver and
       
    18 *                sends them to the database. All received messages are
       
    19 *                sent to CCbsReceiverHelper instance by CCbsRecEtel.
       
    20 *                This class makes subscription and existence checks
       
    21 *                to these messages and also implements topic detection feature.
       
    22 *
       
    23 */
       
    24 
       
    25 
       
    26 // INCLUDE FILES
       
    27 #include <barsc.h>              // Resource access
       
    28 #include <barsread.h>           // Resource access
       
    29 
       
    30 #include <CbsServer.rsg>
       
    31 
       
    32 #include "CbsCommon.h"
       
    33 #include "CbsUtils.h"
       
    34 #include "CbsServerPanic.h"
       
    35 #include "CCbsServer.h"
       
    36 #include "CCbsReceiverHelper.h"
       
    37 #include "CCbsDbImp.H"
       
    38 #include "CCbsDbImpSettings.H"
       
    39 #include "CCbsDbImpTopicList.h"
       
    40 #include "CCbsDbImpTopicMessages.h"
       
    41 #include "CCbsDbImpTopicCollection.h"
       
    42 #include "CCbsRecMessage.h"
       
    43 #ifndef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    44 #include <viewcli.h>            // View server access
       
    45 #else
       
    46 #include <viewclipartner.h>
       
    47 #endif
       
    48 #include <AknNotifyStd.h>       // ECellBroadcastNotification
       
    49 #include <AknSoftNotifier.h>    // Soft Notification API
       
    50 #include <e32property.h>
       
    51 #include <coreapplicationuisdomainpskeys.h>
       
    52 // <-- QT PHONE START -->
       
    53 //#include <NcnListDomainPSKeys.h> 
       
    54 // <-- QT PHONE END -->
       
    55 
       
    56 #include <data_caging_path_literals.hrh>
       
    57 #include "CbsLogger.h"
       
    58 
       
    59 #include <centralrepository.h>  // for local variation
       
    60 #include "cbsinternalcrkeys.h"  // for local variation
       
    61 #include "cbsvariant.hrh"       // for local variation
       
    62 
       
    63 // CONSTANTS
       
    64 
       
    65 // UID of CBS UI application
       
    66 #define KUidCbsUiappDef 0x101F4CD3
       
    67 const TUid KUidCbsUiappApp = { KUidCbsUiappDef };
       
    68 
       
    69 const TInt KCbsImmediateMessageIdInt = 313;
       
    70 const TUid KCbsImmediateMessageId = { KCbsImmediateMessageIdInt };
       
    71 // <-- QT PHONE START -->
       
    72 //const TInt KCbsMessageTone  = 2; // See SharedDataKeysVariant.h or NcnListInternalPSKeys.h
       
    73 // <-- QT PHONE END -->
       
    74 // DATA TYPES
       
    75 // CbsUi application view ID's
       
    76 enum TCbsUiViewIds
       
    77     {
       
    78     ECbsUiTopicViewId = 1,
       
    79     ECbsUiTopicListViewId,
       
    80     ECbsUiListAppColumnViewId,
       
    81     ECbsUiMsgViewId,            //message view id
       
    82     ECbsUiAddFromIndexViewId,
       
    83     ECbsUiSettingsViewId
       
    84     };
       
    85 
       
    86 // These values specify a range of accepted topic number values (inclusive).
       
    87 const TUint KMinTopicNumber = 1;     // 000 is not accepted.
       
    88 const TUint KMaxTopicNumber = 999;
       
    89 
       
    90 // LOCAL FUNCTION PROTOTYPES
       
    91 LOCAL_C void ParseMessageFormatL(
       
    92     TLex& aLex, CCbsDbImpTopicCollection& aCollection );
       
    93 LOCAL_C void ParseIndexElementIntroL(
       
    94     TLex& aLex, CCbsDbImpTopicCollection& aCollection );
       
    95 LOCAL_C void ParseServiceIntroL(
       
    96     TLex& aLex, CCbsDbImpTopicCollection& aCollection );
       
    97 LOCAL_C void ParseMessageIdL(
       
    98     TLex& aLex, TUint& aMessageId );
       
    99 LOCAL_C void ParseSubIndexIntroL(
       
   100     TLex& aLex );
       
   101 LOCAL_C void ParseSubIndexIdL(
       
   102     TLex& aLex );
       
   103 LOCAL_C void ParseNameCharactersCrLfL(
       
   104     TLex& aLex, TPtrC& aName );
       
   105 
       
   106 // ==================== LOCAL FUNCTIONS ====================
       
   107 
       
   108 // -----------------------------------------------------------------------------
       
   109 // ParseMessageFormatL
       
   110 // Parses an index message.
       
   111 // Returns: None
       
   112 // -----------------------------------------------------------------------------
       
   113 //
       
   114 LOCAL_C void ParseMessageFormatL(
       
   115     TLex& aLex,
       
   116     CCbsDbImpTopicCollection& aCollection )
       
   117     {
       
   118     TInt identitiesCount( 0 );
       
   119     while ( !aLex.Eos() )
       
   120         {
       
   121         ParseIndexElementIntroL( aLex, aCollection );
       
   122         identitiesCount++;
       
   123         }
       
   124 
       
   125     if ( identitiesCount == 0 )
       
   126         {
       
   127         User::Leave( KErrCorrupt );
       
   128         }
       
   129     }
       
   130 
       
   131 // -----------------------------------------------------------------------------
       
   132 // ParseIndexElementIntroL
       
   133 // Parses part of an index message.
       
   134 // Returns: None
       
   135 // -----------------------------------------------------------------------------
       
   136 //
       
   137 LOCAL_C void ParseIndexElementIntroL(
       
   138     TLex& aLex,
       
   139     CCbsDbImpTopicCollection& aCollection )
       
   140     {
       
   141     TBool hasSubIndexId( EFalse );
       
   142 
       
   143     // subindex-id (optional for service-intro)
       
   144     if ( aLex.Peek().IsAlpha() )
       
   145         {
       
   146         hasSubIndexId = ETrue;
       
   147         ParseSubIndexIdL( aLex );
       
   148         }
       
   149 
       
   150     // subindex-intro | service-intro
       
   151     // We'll take a peek to discover, which one
       
   152     if ( hasSubIndexId && aLex.Peek() == EKeySpace )
       
   153         {
       
   154         ParseSubIndexIntroL( aLex );
       
   155         }
       
   156     else
       
   157         {
       
   158         ParseServiceIntroL( aLex, aCollection );
       
   159         }
       
   160     }
       
   161 
       
   162 // -----------------------------------------------------------------------------
       
   163 // ParseServiceIntroL
       
   164 // Parses part of an index message.
       
   165 // Returns: None
       
   166 // -----------------------------------------------------------------------------
       
   167 //
       
   168 LOCAL_C void ParseServiceIntroL(
       
   169     TLex& aLex,
       
   170     CCbsDbImpTopicCollection& aCollection )
       
   171     {
       
   172     // We'll store the results here
       
   173     TCbsDbTopicIdentity identity;
       
   174 
       
   175     // message-id
       
   176     TUint messageId;
       
   177     ParseMessageIdL( aLex, messageId );
       
   178     identity.iNumber = TUint16( messageId );
       
   179 
       
   180     // delimeter
       
   181     TChar delimeter( aLex.Get() );
       
   182     if ( delimeter != ' ' && delimeter != '.' )
       
   183         {
       
   184         User::Leave( KErrCorrupt );
       
   185         }
       
   186 
       
   187     // service-name
       
   188     TPtrC serviceName;
       
   189     ParseNameCharactersCrLfL( aLex, serviceName );
       
   190     // drop crlf
       
   191     serviceName.Set( serviceName.Left( serviceName.Length()-2 ) );
       
   192 
       
   193     // If the delimeter is ' ', store the identity. Otherwise
       
   194     // it only refers to a subindex page, so we skip it
       
   195     if ( delimeter == ' ' )
       
   196         {
       
   197         // Copy max. KCbsDbTopicNameLength characters
       
   198         identity.iName = serviceName.Left( KCbsDbTopicNameLength );
       
   199         // Store the topic identity into the database
       
   200         aCollection.AddTopicIdentityL( identity );
       
   201         }
       
   202     }
       
   203 
       
   204 // -----------------------------------------------------------------------------
       
   205 // ParseMessageIdL
       
   206 // Parses part of an index message.
       
   207 // Returns: None
       
   208 // -----------------------------------------------------------------------------
       
   209 //
       
   210 LOCAL_C void ParseMessageIdL(
       
   211     TLex& aLex,
       
   212     TUint& aMessageId )
       
   213     {
       
   214     if ( aLex.Val( aMessageId ) != KErrNone
       
   215         || aMessageId < KMinTopicNumber
       
   216         || aMessageId > KMaxTopicNumber )
       
   217         {
       
   218         User::Leave( KErrCorrupt );
       
   219         }
       
   220     }
       
   221 
       
   222 // -----------------------------------------------------------------------------
       
   223 // ParseSubIndexIntroL
       
   224 // Parses part of an index message.
       
   225 // subindex-intro = " " subindex-name crlf
       
   226 // subindex-name  = name-character+
       
   227 // Returns: None
       
   228 // -----------------------------------------------------------------------------
       
   229 //
       
   230 LOCAL_C void ParseSubIndexIntroL(
       
   231     TLex& aLex )
       
   232     {
       
   233     if ( aLex.Get() != EKeySpace )
       
   234         {
       
   235         User::Leave( KErrCorrupt );
       
   236         }
       
   237 
       
   238     // subindex-name crlf
       
   239     TPtrC subIndexName;
       
   240     ParseNameCharactersCrLfL( aLex, subIndexName );
       
   241     }
       
   242 
       
   243 // -----------------------------------------------------------------------------
       
   244 // ParseSubIndexIdL
       
   245 // Parses part of an index message.
       
   246 // subindex-id = subindex-character+
       
   247 // Returns: None
       
   248 // -----------------------------------------------------------------------------
       
   249 //
       
   250 LOCAL_C void ParseSubIndexIdL(
       
   251     TLex& aLex )
       
   252     {
       
   253     // check that there is at least one subindex-character
       
   254     if ( !aLex.Peek().IsAlpha() )
       
   255         {
       
   256         User::Leave( KErrCorrupt );
       
   257         }
       
   258 
       
   259     // subindex-id
       
   260     while ( aLex.Peek().IsAlpha() )
       
   261         {
       
   262         aLex.Inc();
       
   263         }
       
   264     }
       
   265 
       
   266 // -----------------------------------------------------------------------------
       
   267 // ParseNameCharactersCrLfL
       
   268 // Parses part of an index message.
       
   269 // name-character+ crlf
       
   270 // Returns: None
       
   271 // -----------------------------------------------------------------------------
       
   272 //
       
   273 LOCAL_C void ParseNameCharactersCrLfL(
       
   274     TLex& aLex,
       
   275     TPtrC& aName )
       
   276     {
       
   277     aLex.Mark();
       
   278 
       
   279     // check that we have at least one name-character
       
   280     TChar currCharacter( aLex.Get() );
       
   281     if( currCharacter == EKeyLineFeed
       
   282         || currCharacter == EKeyEnter
       
   283         || currCharacter == 0 )
       
   284         {
       
   285         User::Leave( KErrCorrupt );
       
   286         }
       
   287 
       
   288     // scan until LF or EOS
       
   289     while( currCharacter != EKeyLineFeed && currCharacter != 0 )
       
   290         {
       
   291         currCharacter = aLex.Get();
       
   292         }
       
   293 
       
   294     // CR-LF is ok, EOS is not
       
   295     if( currCharacter == EKeyLineFeed )
       
   296         {
       
   297         aName.Set( aLex.MarkedToken() );
       
   298         }
       
   299     else
       
   300         {
       
   301         User::Leave( KErrCorrupt );
       
   302         }
       
   303     }
       
   304 
       
   305 // ================= MEMBER FUNCTIONS =======================
       
   306 
       
   307 // -----------------------------------------------------------------------------
       
   308 // CCbsReceiverHelper::CCbsReceiverHelper
       
   309 // C++ default constructor can NOT contain any code, that
       
   310 // might leave.
       
   311 // -----------------------------------------------------------------------------
       
   312 //
       
   313 CCbsReceiverHelper::CCbsReceiverHelper(
       
   314     CCbsDbImp& aDatabase )
       
   315     : iDatabase( aDatabase )
       
   316     {
       
   317     }
       
   318 
       
   319 // -----------------------------------------------------------------------------
       
   320 // CCbsReceiverHelper::ConstructL
       
   321 // Symbian 2nd phase constructor can leave.
       
   322 // -----------------------------------------------------------------------------
       
   323 //
       
   324 void CCbsReceiverHelper::ConstructL()
       
   325     {
       
   326     CBSLOGSTRING("CBSSERVER: >>> CCbsReceiverHelper::ConstructL()");
       
   327 
       
   328     iVwsSession = CVwsSessionWrapper::NewL();
       
   329 
       
   330     // Array for SIM Topic numbers. This way we know which topics
       
   331     // to delete also from the SIM card (when deleting all topics).
       
   332     iSimTopics = new ( ELeave ) CArrayFixFlat<TInt>( 1 );
       
   333     
       
   334     // Fetch local variation bits from CenRep    
       
   335     CRepository* repository = CRepository::NewL( KCRUidCbsVariation );    
       
   336     TInt err = repository->Get( KCbsVariationFlags, iLVBits );
       
   337     if ( err )
       
   338         {
       
   339         iLVBits = 0;
       
   340         }  
       
   341     CBSLOGSTRING2("CBSSERVER: CCbsRecEtel::ConstructL(): CenRep error: %d", err );
       
   342     delete repository;
       
   343 
       
   344     CBSLOGSTRING("CBSSERVER: <<< CCbsReceiverHelper::ConstructL()");
       
   345     }
       
   346 
       
   347 // -----------------------------------------------------------------------------
       
   348 // CCbsReceiverHelper::NewL
       
   349 // Two-phased constructor.
       
   350 // -----------------------------------------------------------------------------
       
   351 //
       
   352 CCbsReceiverHelper* CCbsReceiverHelper::NewL(
       
   353     CCbsDbImp& aDatabase )
       
   354     {
       
   355     // Normal two phase construction.
       
   356     CCbsReceiverHelper* self = new ( ELeave ) CCbsReceiverHelper( aDatabase );
       
   357     CleanupStack::PushL( self );
       
   358     self->ConstructL();
       
   359     CleanupStack::Pop();
       
   360     return self;
       
   361     }
       
   362 
       
   363 // Destructor
       
   364 CCbsReceiverHelper::~CCbsReceiverHelper()
       
   365     {
       
   366     CBSLOGSTRING("CBSSERVER: >>> CCbsReceiverHelper::~CCbsReceiverHelper()");
       
   367 
       
   368     delete iSimTopics;
       
   369     delete iVwsSession;
       
   370 
       
   371     CBSLOGSTRING("CBSSERVER: <<< CCbsReceiverHelper::~CCbsReceiverHelper()");
       
   372     }
       
   373 
       
   374 // -----------------------------------------------------------------------------
       
   375 // CCbsReceiverHelper::CCbsReceiverHelper
       
   376 // Processes a message received by the receiver.
       
   377 //
       
   378 // This function is called when a message is received.
       
   379 //
       
   380 // Assumptions;
       
   381 // 1.  The message doesn't have it's permanent or read
       
   382 //     flags raised - method leaves with KErrNotSupported
       
   383 //     if this is the case.
       
   384 // 2.  If an index message (root or subindex) is passed as
       
   385 //     a parameter, the language indication prefix, if any,
       
   386 //     has been removed before HandleReceivedMessageL() is called.
       
   387 //
       
   388 // Assumption (2) holds because language indications are removed
       
   389 // by Receiver module in an instance of CCbsRecDecoder.
       
   390 // Message may not be accepted if it is somehow invalid
       
   391 // or the reception has been disabled.
       
   392 // This function also handles the detection of new topics
       
   393 // and the processing of an index message.
       
   394 // (other items were commented in a header).
       
   395 // -----------------------------------------------------------------------------
       
   396 //
       
   397 void CCbsReceiverHelper::HandleReceivedMessageL(
       
   398     CCbsMessage& aMessage )
       
   399     {
       
   400     CBSLOGSTRING("CBSSERVER: >>> CCbsReceiverHelper::HandleReceivedMessageL()");
       
   401 
       
   402     if ( aMessage.IsIndexMessage() )
       
   403         {
       
   404         CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): Index msg.");
       
   405 
       
   406         // It is assumed that a language indication prefix,
       
   407         // if any, has already been removed from the message.
       
   408         aMessage.RemoveIndexHeaderL();
       
   409 
       
   410         TBool isChildSubindex( aMessage.IsChildSubindex() );
       
   411 
       
   412         // Parse the index message
       
   413         HandleIndexMessageL( aMessage.Contents(), isChildSubindex );
       
   414 
       
   415         // Child subindex messages won't be displayed to the user.
       
   416         if ( isChildSubindex )
       
   417             {
       
   418             return;
       
   419             }
       
   420         }
       
   421 
       
   422     TUint16 topicNumber( aMessage.TopicNumber() );
       
   423     CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): topic number: %d.", topicNumber );
       
   424 
       
   425     TCbsDbTopic topic;
       
   426     iDatabase.TopicListL().FindTopicByNumberL( topicNumber, topic );
       
   427     CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): iDatabase.TopicListL().FindTopicByNumberL(..) called OK." );
       
   428 
       
   429     // If subscribed, handle the message
       
   430     if ( topic.iSubscribed )
       
   431         {
       
   432         CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): Topic subscribed, processing." );
       
   433 
       
   434         // Create and initialize message
       
   435         TCbsDbMessage message;
       
   436 
       
   437         TTime now;
       
   438         now.UniversalTime();
       
   439         message.iDateTime = now.Int64();
       
   440         message.iKey = aMessage.Key();
       
   441         message.iLanguage = aMessage.Language();
       
   442         message.iLength = aMessage.Contents().Length();
       
   443         message.iPermanent = EFalse;
       
   444         message.iRead = EFalse;
       
   445         TPtrC ptr( aMessage.Contents() );
       
   446 
       
   447         iDatabase.TopicMessagesL().AddMessageL( topicNumber, message, ptr );
       
   448         CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): Msg added OK." );
       
   449 
       
   450         if ( aMessage.RequiresImmediateDisplay() )
       
   451             {
       
   452             CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): Calling LaunchMessageImmediateDisplay()... " );
       
   453 
       
   454             // If the operator indicates that this message must be displayed
       
   455             // immediately, request a view switch of CBS UI application.
       
   456             LaunchMessageImmediateDisplay( message );
       
   457 
       
   458             CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): LaunchMessageImmediateDisplay() called OK." );
       
   459             }
       
   460         else if ( topic.iHotmarked )
       
   461             {
       
   462             // The message is of a hotmarked topic => Show a soft notification.
       
   463             CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): Calling LaunchMessageSoftNotification()... " );
       
   464             LaunchMessageSoftNotificationL( ETrue );
       
   465             CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): LaunchMessageSoftNotification() called OK." );
       
   466             }
       
   467         } // if ( topic.iSubscribed )
       
   468     else
       
   469         {
       
   470         CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): Topic NOT subscribed, msg not processed." );
       
   471         }
       
   472 
       
   473     CBSLOGSTRING("CBSSERVER: <<< CCbsReceiverHelper::HandleReceivedMessageL()");
       
   474     }
       
   475 
       
   476 // -----------------------------------------------------------------------------
       
   477 // CCbsReceiverHelper::CheckForNewTopicL
       
   478 // Checks if aMessage's topic is in the topic list.
       
   479 //
       
   480 // If the topic detection is enabled and the topic of this
       
   481 // message is not in the topic list, the topic is added
       
   482 // to the list. The method will then return ETrue.
       
   483 // Otherwise EFalse is returned.
       
   484 // (other items were commented in a header).
       
   485 // -----------------------------------------------------------------------------
       
   486 //
       
   487 TBool CCbsReceiverHelper::CheckForNewTopicL(
       
   488     const CCbsMessage& aMessage )
       
   489     {
       
   490     // Check if the topic detection is on and if so, add topic if the topic
       
   491     // is a new topic.
       
   492     TBool detection;
       
   493     TBool result( EFalse );
       
   494 
       
   495     iDatabase.SettingsL().GetTopicDetectionStatus( detection );
       
   496 
       
   497     if ( detection && HandleTopicDetectedL( aMessage.TopicNumber() ) )
       
   498         {
       
   499         // If a new topic added, we do not send the message to
       
   500         // the database so return ETrue.
       
   501         result = ETrue;
       
   502         }
       
   503     else
       
   504         {
       
   505         // Topic detection disabled or topic already in the database
       
   506         result = EFalse;
       
   507         }
       
   508 
       
   509     return result;
       
   510     }
       
   511 
       
   512 // -----------------------------------------------------------------------------
       
   513 // CCbsReceiverHelper::CheckForSubscriptionAndExistenceL
       
   514 // Checks if the topic of this message is listed and subscribed.
       
   515 // Returns ETrue only if the message does not exist in the
       
   516 // database and the message's topic is subscribed.
       
   517 // (other items were commented in a header).
       
   518 // -----------------------------------------------------------------------------
       
   519 //
       
   520 TBool CCbsReceiverHelper::CheckForSubscriptionAndExistenceL(
       
   521     const CCbsMessage& aMessage )
       
   522     {
       
   523     // Check if the message belongs to some subscribed topic.
       
   524     TCbsDbTopic topic;
       
   525     TUint16 topicNumber( 0 );
       
   526 
       
   527     // Index messages are stored in topic 0.
       
   528     if ( !aMessage.IsIndexMessage() )
       
   529         {
       
   530         topicNumber = aMessage.TopicNumber();
       
   531         }
       
   532 
       
   533     TRAPD( errorCode, iDatabase.TopicListL().FindTopicByNumberL( topicNumber, topic ) );
       
   534 
       
   535     if ( errorCode == KErrNotFound )
       
   536         {
       
   537         return EFalse;
       
   538         }
       
   539     User::LeaveIfError( errorCode );
       
   540 
       
   541     return topic.iSubscribed;
       
   542     }
       
   543 
       
   544 // -----------------------------------------------------------------------------
       
   545 // CCbsReceiverHelper::LanguageOfMessageSubscribedL
       
   546 // Checks if aMessage's language has been subscribed by the user.
       
   547 // ETrue is returned either if the language specified has been
       
   548 // subscribed, message language is "Other" or the user has
       
   549 // prefers to receive messages of all languages.
       
   550 // (other items were commented in a header).
       
   551 // -----------------------------------------------------------------------------
       
   552 //
       
   553 TBool CCbsReceiverHelper::LanguageOfMessageSubscribedL(
       
   554     const CCbsMessage& aMessage )
       
   555     {
       
   556     CBSLOGSTRING("CBSSERVER: >>> CCbsReceiverHelper::LanguageOfMessageSubscribedL" );
       
   557 
       
   558     TCbsDbLanguages languages;
       
   559     iDatabase.SettingsL().GetLanguages( languages );
       
   560 
       
   561     if ( aMessage.Language() < 0 || aMessage.Language() >= ECbsCount )
       
   562         {
       
   563         return EFalse;
       
   564         }
       
   565 
       
   566     TCbsDbLanguage language( aMessage.Language() );
       
   567     CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::LanguageOfMessageSubscribedL: language: %d.", language );
       
   568 
       
   569     TBool subscribed( languages.iLanguages[ECbsAll] ||
       
   570         languages.iLanguages[ECbsOther] && language == ECbsOther ||
       
   571         !languages.iLanguages[ECbsOther] && languages.iLanguages[language] );
       
   572 
       
   573     CBSLOGSTRING2("CBSSERVER: <<< CCbsReceiverHelper::LanguageOfMessageSubscribedL, returning %d.", subscribed );
       
   574     return subscribed;
       
   575     }
       
   576 
       
   577 // ---------------------------------------------------------
       
   578 // AddSimTopicL()
       
   579 //
       
   580 // Adds the given topic (aNumber, aName) into the DB.
       
   581 // ---------------------------------------------------------
       
   582 void CCbsReceiverHelper::AddSimTopicL( 
       
   583     const TUint aNumber,
       
   584     const TDesC& aName )
       
   585     {
       
   586     CBSLOGSTRING("CBSSERVER: >>> CCbsReceiverHelper::AddSimTopicL()");
       
   587 
       
   588     TCbsDbTopic topic;
       
   589     if ( aName == KNullDesC )       // Topic name not given, use "SIM topics".
       
   590         {
       
   591         // Establish file server session.
       
   592         RFs fs;
       
   593         User::LeaveIfError( fs.Connect() );
       
   594         CleanupClosePushL( fs );
       
   595 
       
   596         // Open localized resource file.
       
   597         RResourceFile resourceFile;
       
   598         CbsUtils::FindAndOpenDefaultResourceFileLC(
       
   599             fs, resourceFile ); // on CS
       
   600 
       
   601         // Read "SIM topic"-string.
       
   602         TResourceReader reader;
       
   603         reader.SetBuffer( resourceFile.AllocReadLC(
       
   604             R_TEXT_SIM_TOPIC ) ); // on CS
       
   605 
       
   606         HBufC* text = reader.ReadHBufCL();
       
   607         topic.iName = *text;
       
   608         CleanupStack::PopAndDestroy(3);  // fs, resourceFile, readerBuf
       
   609 
       
   610         CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::AddSimTopicL(): Topic name read from resources.");
       
   611         }
       
   612     else // Use the given topic name.
       
   613         {
       
   614         topic.iName = aName;
       
   615         }
       
   616 
       
   617     topic.iNumber = TUint16( aNumber );
       
   618     topic.iHotmarked = EFalse;
       
   619     topic.iProtected = EFalse;
       
   620     
       
   621     // Variated feature    
       
   622     if ( iLVBits & KCbsLVFlagTopicSubscription )
       
   623         {
       
   624         topic.iSubscribed = ETrue;
       
   625         }
       
   626     else
       
   627         {
       
   628         topic.iSubscribed = EFalse;
       
   629         }
       
   630 
       
   631     // Leaves, if the topic already exists, so we trap that
       
   632     // error. All other errors are passed as a normal leave.
       
   633     CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::AddSimTopicL(): Topic %d from SIM to topic list...", topic.iNumber );
       
   634     // Try to add topic to topic list, topic not detected automatically
       
   635     TRAPD( err, iDatabase.TopicListL().AddTopicL( topic, EFalse ) );
       
   636     CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::AddSimTopicL(): AddTopicL() TRAPped error: %d.", err );
       
   637 
       
   638     if( err != KErrAlreadyExists && err != KErrArgument )
       
   639         {
       
   640         CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::AddSimTopicL(): Leave if error != -11 || -6");
       
   641         User::LeaveIfError( err );
       
   642         }
       
   643 
       
   644     // Append to SIM Topic array
       
   645     iSimTopics->AppendL( topic.iNumber );
       
   646     CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::AddSimTopicL(): Topic %d appended to array.", topic.iNumber ); 
       
   647     
       
   648     // Leave so that caller is informed e.g. if topic already exists
       
   649     User::LeaveIfError( err );
       
   650     CBSLOGSTRING("CBSSERVER: <<< CCbsReceiverHelper::AddSimTopicL()" );
       
   651     
       
   652     }
       
   653 
       
   654 // -----------------------------------------------------------------------------
       
   655 // CCbsReceiverHelper::SimTopics
       
   656 // Returns topics currently added from the SIM card.
       
   657 // (other items were commented in a header).
       
   658 // -----------------------------------------------------------------------------
       
   659 //
       
   660 CArrayFixFlat<TInt>& CCbsReceiverHelper::SimTopics() const
       
   661     {
       
   662     return *iSimTopics;
       
   663     }
       
   664 
       
   665 // -----------------------------------------------------------------------------
       
   666 // CCbsReceiverHelper::DeleteFromSimTopicCache
       
   667 // Deletes the topic number from local SIM Topic array.
       
   668 // (other items were commented in a header).
       
   669 // -----------------------------------------------------------------------------
       
   670 //
       
   671 void CCbsReceiverHelper::DeleteFromSimTopicCache( const TUint16 aNumber )
       
   672     {
       
   673     CBSLOGSTRING("CBSSERVER: >>> CCbsReceiverHelper::DeleteFromSimTopicCache()");
       
   674     CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::DeleteFromSimTopicCache(): Topic number: %d", aNumber );
       
   675     CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::DeleteFromSimTopicCache(): Topic count in cache (1): %d", iSimTopics->Count() );
       
   676 
       
   677     // Check if this topic is a SIM Topic (can be found in the array)
       
   678     TKeyArrayFix key( 0, ECmpTUint16 );
       
   679     TInt index;
       
   680     TUint16 topicNumber( aNumber );
       
   681     TInt result( iSimTopics->FindIsq( topicNumber, key, index ) );
       
   682 
       
   683     CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::DeleteFromSimTopicCache(): FindIsq() result: %d", result );
       
   684     CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::DeleteFromSimTopicCache(): FindIsq() result, position: %d", index );
       
   685 
       
   686     // Delete the topic from the array
       
   687     if ( result == KErrNone )
       
   688         {
       
   689         CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::DeleteFromSimTopicCache(): Topic no. %d found from cache.", aNumber );
       
   690         iSimTopics->Delete( index );
       
   691         CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::DeleteFromSimTopicCache(): Topic deleted from cache, index: %d", index );
       
   692         iSimTopics->Compress();
       
   693         CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::DeleteFromSimTopicCache(): SIM Topic array compressed.");
       
   694         }
       
   695 
       
   696     CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::DeleteFromSimTopicCache(): Topic count in cache (2): %d", iSimTopics->Count() );
       
   697     CBSLOGSTRING("CBSSERVER: <<< CCbsReceiverHelper::DeleteFromSimTopicCache()");
       
   698     }
       
   699 
       
   700 // -----------------------------------------------------------------------------
       
   701 // CCbsReceiverHelper::Database
       
   702 // Returns a reference to the CCbsDbImp instance.
       
   703 // If a topic of the same number already exists
       
   704 // in DB, does nothing.
       
   705 // (other items were commented in a header).
       
   706 // -----------------------------------------------------------------------------
       
   707 //
       
   708 CCbsDbImp& CCbsReceiverHelper::Database() const
       
   709     {
       
   710     return iDatabase;
       
   711     }
       
   712 
       
   713 // -----------------------------------------------------------------------------
       
   714 // CCbsReceiverHelper::TopicsDetected
       
   715 // Returns the number of detected topics.
       
   716 // (other items were commented in a header).
       
   717 // -----------------------------------------------------------------------------
       
   718 //
       
   719 TUint CCbsReceiverHelper::TopicsDetected() const
       
   720     {
       
   721     return iTopicsDetected;
       
   722     }
       
   723 
       
   724 // -----------------------------------------------------------------------------
       
   725 // CCbsReceiverHelper::ClearTopicsDetectedCounter
       
   726 // Sets the counter for detected topics to zero.
       
   727 // (other items were commented in a header).
       
   728 // -----------------------------------------------------------------------------
       
   729 //
       
   730 void CCbsReceiverHelper::ClearTopicsDetectedCounter()
       
   731     {
       
   732     // Clear the variable indicating the amount of detected topics.
       
   733     iTopicsDetected = 0;
       
   734     }
       
   735 
       
   736 // -----------------------------------------------------------------------------
       
   737 // CCbsReceiverHelper::HandleTopicDetectedL
       
   738 // Handles detected topic.
       
   739 // (other items were commented in a header).
       
   740 // -----------------------------------------------------------------------------
       
   741 //
       
   742 TBool CCbsReceiverHelper::HandleTopicDetectedL(
       
   743     const TCbsDbTopicNumber& iTopicNumber )
       
   744     {
       
   745     // Create new topic and initialise it.
       
   746     TCbsDbTopic topic;
       
   747     topic.iNumber = iTopicNumber;
       
   748     topic.iName = KNullDesC;
       
   749     topic.iProtected = EFalse;
       
   750     topic.iSubscribed = EFalse;
       
   751     topic.iHotmarked = EFalse;
       
   752 
       
   753     TBool result( ETrue );
       
   754 
       
   755     // Try to add the topic. If succeeded,
       
   756     // increase counter iTopicsDetected.
       
   757     TRAPD( error, iDatabase.TopicListL().AddTopicL( topic, ETrue ) );
       
   758 
       
   759     if ( error == KErrAlreadyExists )
       
   760         {
       
   761         result = EFalse;
       
   762         }
       
   763     else if ( error != KErrNone && error != KErrAlreadyExists )
       
   764         {
       
   765         User::Leave( error );
       
   766         }
       
   767     else
       
   768         {
       
   769         // Update the detected topics counter
       
   770         iTopicsDetected++;
       
   771         }
       
   772     return result;
       
   773     }
       
   774 
       
   775 // -----------------------------------------------------------------------------
       
   776 // CCbsReceiverHelper::HandleIndexMessageL
       
   777 // Processes an index message and builds a new topic collection
       
   778 // (other items were commented in a header).
       
   779 // -----------------------------------------------------------------------------
       
   780 //
       
   781 void CCbsReceiverHelper::HandleIndexMessageL(
       
   782     const TDesC& aContents,
       
   783     const TBool aIsChildSubIndex )
       
   784     {
       
   785     // Previous topic identities are cleared if a root index message
       
   786     // is received.
       
   787     if ( !aIsChildSubIndex )
       
   788         {
       
   789         iDatabase.TopicCollectionL().Clear();
       
   790         }
       
   791     // Parses topic identities from the index message.
       
   792     // The identities are stored in the current topic collection.
       
   793     // If the index message is corrupt, it should still be stored,
       
   794     // so trap the error.
       
   795     TLex lex( aContents );
       
   796     TRAPD( error, ParseMessageFormatL( lex, iDatabase.TopicCollectionL() ) );
       
   797     switch ( error )
       
   798         {
       
   799         case KErrNone:
       
   800             // If the message all went fine, apply.
       
   801             // The topic identities are written into persistent memory.
       
   802             iDatabase.TopicCollectionL().Apply();
       
   803             break;
       
   804 
       
   805         case KErrCorrupt:
       
   806             // Do not react on corrupt messages.
       
   807             break;
       
   808 
       
   809         default:
       
   810             // All other errors will prevent saving the message.
       
   811             User::Leave( error );
       
   812             break;
       
   813         }
       
   814     }
       
   815 
       
   816 // -----------------------------------------------------------------------------
       
   817 // CCbsReceiverHelper::ParseTopicIdentitiesL
       
   818 // Parses all topic identities from aText which is assumed to be
       
   819 // an index message's content.
       
   820 // (other items were commented in a header).
       
   821 // -----------------------------------------------------------------------------
       
   822 //
       
   823 void CCbsReceiverHelper::ParseTopicIdentitiesL(
       
   824         const TDesC& aText )
       
   825     {
       
   826     // Create a lexer and pass it to the parser
       
   827     TLex lex( aText );
       
   828 
       
   829     ParseMessageFormatL( lex, iDatabase.TopicCollectionL() );
       
   830     }
       
   831 
       
   832 // -----------------------------------------------------------------------------
       
   833 // CCbsReceiverHelper::LaunchMessageSoftNotificationL
       
   834 // Requests to launch a soft notification.
       
   835 // (other items were commented in a header).
       
   836 // -----------------------------------------------------------------------------
       
   837 //
       
   838 void CCbsReceiverHelper::LaunchMessageSoftNotificationL( const TBool aPlayTone )
       
   839     {
       
   840     TInt numberOfHotMsgs( 0 );
       
   841     numberOfHotMsgs = iDatabase.TopicListL().UnreadHotmarkedMessageCount();
       
   842 
       
   843     CAknSoftNotifier* notifier = CAknSoftNotifier::NewLC(); // on CS
       
   844 
       
   845     TurnLightsOn();
       
   846 
       
   847     if ( aPlayTone )
       
   848         {
       
   849         PlayCbsTone();
       
   850         }
       
   851 
       
   852     notifier->SetNotificationCountL( ECellBroadcastNotification, numberOfHotMsgs );
       
   853     CleanupStack::PopAndDestroy( notifier );
       
   854     }
       
   855 
       
   856 // -----------------------------------------------------------------------------
       
   857 // CCbsReceiverHelper::LaunchMessageImmediateDisplay
       
   858 // Requests to show the message immediately.
       
   859 // (other items were commented in a header).
       
   860 // -----------------------------------------------------------------------------
       
   861 //
       
   862 void CCbsReceiverHelper::LaunchMessageImmediateDisplay(
       
   863     const TCbsDbMessage& aMessage )
       
   864     {
       
   865     TUid uiViewUid( TUid::Uid( ECbsUiMsgViewId ) );
       
   866     TVwsViewId id( KUidCbsUiappApp, uiViewUid );
       
   867     TPckgBuf<TCbsMessageHandle> pckg( aMessage.iHandle );
       
   868 
       
   869     // Ignore result value.
       
   870     iVwsSession->CreateActivateViewEvent( id, KCbsImmediateMessageId, pckg );
       
   871     }
       
   872 
       
   873 // -----------------------------------------------------------------------------
       
   874 // CCbsReceiverHelper::TurnLightsOn
       
   875 // Turns lights on
       
   876 // -----------------------------------------------------------------------------
       
   877 //
       
   878 void CCbsReceiverHelper::TurnLightsOn()
       
   879     {
       
   880      // Change the bit on and off. SysAp will detect that
       
   881      // the lights should be switched on for the specified time.
       
   882      RProperty::Set(KPSUidCoreApplicationUIs, KLightsControl, ELightsOn);
       
   883      RProperty::Set(KPSUidCoreApplicationUIs, KLightsControl, ELightsOff);
       
   884     }
       
   885 
       
   886 // -----------------------------------------------------------------------------
       
   887 // CCbsReceiverHelper::PlayCbsTone
       
   888 // Plays a tone
       
   889 // -----------------------------------------------------------------------------
       
   890 //
       
   891 void CCbsReceiverHelper::PlayCbsTone()
       
   892     {
       
   893     // <-- QT PHONE START -->
       
   894     /*
       
   895     RProperty::Define( KPSUidNcnList, KNcnPlayAlertTone, RProperty::EInt,
       
   896         ECapability_None , ECapabilityWriteDeviceData );
       
   897     RProperty::Set( KPSUidNcnList, KNcnPlayAlertTone, KCbsMessageTone );
       
   898     */
       
   899     // <-- QT PHONE END-->
       
   900     }
       
   901 
       
   902 // ================= OTHER EXPORTED FUNCTIONS ==============
       
   903 
       
   904 //  End of File
       
   905