calendarengines/caleninterimutils/src/CalenInterimUtils2Impl.cpp
branchRCL_3
changeset 30 bd7edf625bdd
parent 29 12af337248b1
equal deleted inserted replaced
29:12af337248b1 30:bd7edf625bdd
    30 #include <caluser.h>
    30 #include <caluser.h>
    31 #include <calentryview.h>
    31 #include <calentryview.h>
    32 #include <etelmm.h>
    32 #include <etelmm.h>
    33 #include <e32math.h>
    33 #include <e32math.h>
    34 #include <calrrule.h>
    34 #include <calrrule.h>
       
    35 #include <cmrmailboxutils.h>
    35 #include <featmgr.h>
    36 #include <featmgr.h>
       
    37 #include <MeetingRequestUids.hrh>
    36 #include <ecom/ecom.h>
    38 #include <ecom/ecom.h>
    37 #include <utf.h>
    39 #include <utf.h>
    38 #include <openssl/md5.h>
    40 #include <openssl/md5.h>
    39 #include <string.h>
    41 #include <string.h>
    40 
    42 
    41 #include "CleanupResetAndDestroy.h"
    43 #include "CleanupResetAndDestroy.h"
    42 #include "RImplInfoPtrArrayOwn.inl"
    44 #include "RImplInfoPtrArrayOwn.inl"
    43 #include "CalenEcomWatcher.h"       // Watches for ECOM registry changes
    45 #include "CalenEcomWatcher.h"       // Watches for ECOM registry changes
    44 
    46 
    45 // CONSTANTS
    47 // CONSTANTS
       
    48 
       
    49 /* set the following to the number of 100ns ticks of the actual
       
    50    resolution of your system's clock.
       
    51    800MHZ means 1s->800*(10^6) clock cycles
       
    52    100ns->80 clock cycles*/
       
    53 const TUint16 UUIDS_PER_TICK = 80;
       
    54 
    46 /// Unnamed namespace for local definitions
    55 /// Unnamed namespace for local definitions
    47 namespace {
    56 namespace {
    48 
    57 
    49 #ifdef __WINSCW__
    58 #ifdef __WINSCW__
    50     _LIT( KEmulatorImei, "123456789012345" );
    59     _LIT( KEmulatorImei, "123456789012345" );
    51 #endif
    60 #endif
    52 
    61 
    53     const TInt KImeiLength = 15; // 15 chars from left of imei
    62     const TInt KImeiLength = 15; // 15 chars from left of imei
    54 
    63     const TInt KAsciiFirstNumber = 48;             // ASCII character 48 = '0'.  
    55     const TInt KAsciiFirstNumber = 48;             // ASCII character 48 = '0'.
       
    56     const TInt KAsciiFirstLowercaseLetter = 97;    // ASCII character 97 = 'a'.
    64     const TInt KAsciiFirstLowercaseLetter = 97;    // ASCII character 97 = 'a'.
    57 
    65 
    58 }  // namespace
    66 }  // namespace
    59 
    67 
    60 // ----------------------------------------------------------------------------
    68 // ----------------------------------------------------------------------------
    86 // -----------------------------------------------------------------------------
    94 // -----------------------------------------------------------------------------
    87 CCalenInterimUtils2Impl::CCalenInterimUtils2Impl()
    95 CCalenInterimUtils2Impl::CCalenInterimUtils2Impl()
    88     {
    96     {
    89     TRACE_ENTRY_POINT;
    97     TRACE_ENTRY_POINT;
    90 
    98 
       
    99     iMrEnabledCheck = ETrue;
       
   100     iMrEnabled = EFalse;    
       
   101     iInited = EFalse;
    91     TRACE_EXIT_POINT;
   102     TRACE_EXIT_POINT;
    92     }
   103     }
    93 
   104 
    94 // -----------------------------------------------------------------------------
   105 // -----------------------------------------------------------------------------
    95 // CCalenInterimUtils2Impl::ConstructL()
   106 // CCalenInterimUtils2Impl::ConstructL()
   272     
   283     
   273     // Loosely using UID generation algorithm from
   284     // Loosely using UID generation algorithm from
   274     // http://www.webdav.org/specs/draft-leach-uuids-guids-01.txt
   285     // http://www.webdav.org/specs/draft-leach-uuids-guids-01.txt
   275 
   286 
   276     // Number of 100ns ticks since Oct 15 1582.
   287     // Number of 100ns ticks since Oct 15 1582.
   277     TInt64 timeStamp = GetTicksFromGregorianCalendarStartL();
   288     TInt64 timeStamp;
   278 
   289     GetSystemTime(timeStamp);
       
   290     
   279     // This differs slightly from the spec in that the clock sequence is just a pseudo-random number.
   291     // This differs slightly from the spec in that the clock sequence is just a pseudo-random number.
   280        TUint32 clockSeq = Math::Random();
   292     TUint32 clockSeq = Math::Random();
   281        // IMEI is read the first time this is called, and stored for subsequent calls.
   293     
   282        if(!iImeiNode)
   294     // IMEI is read the first time this is called, and stored for subsequent calls.
   283            {
   295     if(!iImeiNode)
   284            iImeiNode = GetImeiAsNodeValueL();
   296        {
   285            }
   297        iImeiNode = GetImeiAsNodeValueL();
       
   298        }
   286 
   299 
   287     HBufC8* resultBuf = DoCreateUidLC(clockSeq, timeStamp, iImeiNode);
   300     HBufC8* resultBuf = DoCreateUidLC(clockSeq, timeStamp, iImeiNode);
   288     CleanupStack::Pop(resultBuf);
   301     CleanupStack::Pop(resultBuf);
   289     
   302     
   290     TRACE_EXIT_POINT;
   303     TRACE_EXIT_POINT;
   306     TDateTime gregorianStartDT(1582, EOctober, 15, 0, 0, 0, 0);
   319     TDateTime gregorianStartDT(1582, EOctober, 15, 0, 0, 0, 0);
   307     TTime gregorianStart(gregorianStartDT);
   320     TTime gregorianStart(gregorianStartDT);
   308     TTimeIntervalMicroSeconds msDifference = timeNow.MicroSecondsFrom(gregorianStart);
   321     TTimeIntervalMicroSeconds msDifference = timeNow.MicroSecondsFrom(gregorianStart);
   309     
   322     
   310     TRACE_EXIT_POINT;
   323     TRACE_EXIT_POINT;
   311     return msDifference.Int64() * 10; // * 10 to convert from micro sec (==1000 ns) count to 100ns count.
   324     return ( timeNow.Int64() + msDifference.Int64() ) * 10; // * 10 to convert from micro sec (==1000 ns) count to 100ns count.
       
   325     }
       
   326 
       
   327 // -----------------------------------------------------------------------------
       
   328 // CCalenInterimUtils2Impl::GetSystemTime()
       
   329 // This function returns the system time.
       
   330 // (other items were commented in a header).
       
   331 // -----------------------------------------------------------------------------
       
   332 //
       
   333 void CCalenInterimUtils2Impl::GetSystemTime(TInt64& aTimeStamp)
       
   334     {  
       
   335     TRACE_ENTRY_POINT;
       
   336     
       
   337     if (!iInited)
       
   338         {
       
   339         aTimeStamp = GetTicksFromGregorianCalendarStartL();
       
   340         iThisTick = UUIDS_PER_TICK; 
       
   341         iInited = ETrue;
       
   342         }
       
   343     for( ; ; )
       
   344         {
       
   345         aTimeStamp = GetTicksFromGregorianCalendarStartL();
       
   346         //if clock reading changed since last UUID generated...
       
   347         if( iTimeLast != aTimeStamp )
       
   348             {
       
   349             //reset count of uuids gen'd with this clock reading             
       
   350             iThisTick = 0;
       
   351             iTimeLast = aTimeStamp;
       
   352             break;
       
   353             }
       
   354         if( iThisTick < UUIDS_PER_TICK )
       
   355             {
       
   356             iThisTick++;
       
   357             break;
       
   358             }        
       
   359         }
       
   360         //add the count of uuids to low order bits of the clock reading 
       
   361         aTimeStamp += iThisTick;
       
   362         
       
   363     TRACE_EXIT_POINT;
   312     }
   364     }
   313 
   365 
   314 // -----------------------------------------------------------------------------
   366 // -----------------------------------------------------------------------------
   315 // CCalenInterimUtils2Impl::GetImeiAsNodeValueL()
   367 // CCalenInterimUtils2Impl::GetImeiAsNodeValueL()
   316 // Formats the IMEI returned from GetImeiL() into a 64-bit integer.
   368 // Formats the IMEI returned from GetImeiL() into a 64-bit integer.
   363                                                const TUint64& aNodeValue )
   415                                                const TUint64& aNodeValue )
   364     {
   416     {
   365     TRACE_ENTRY_POINT;
   417     TRACE_ENTRY_POINT;
   366     
   418     
   367     // The roast beef of the algorithm. Does all the shifting about as described in the web draft.
   419     // The roast beef of the algorithm. Does all the shifting about as described in the web draft.
   368     TUint32 time_low = aTimeStamp & 0xFFFFFFFF;
   420     SUuid uuid;   
   369     TUint16 time_mid = (aTimeStamp >> 32) & 0xFFFF;
   421     TUint8 hash[16];
   370     TUint16 time_high = (aTimeStamp >> 48) & 0x0FFF;
   422     
   371     time_high |= (1 << 12);
   423     uuid.time_low = aTimeStamp & 0xFFFFFFFF;
   372     TUint8 clock_seq_low = aClockSeq & 0xFF;
   424     uuid.time_mid = (aTimeStamp >> 32) & 0xFFFF;
   373     TUint8 clock_seq_high = (aClockSeq & 0x3F00) >> 8;
   425     uuid.time_high_and_version = (aTimeStamp >> 48) & 0x0FFF;
   374     clock_seq_high |= 0x80;
   426     uuid.time_high_and_version |= (1 << 12);  
   375 
   427     uuid.clock_seq_low = aClockSeq & 0xFF;
   376     // Can't use RArray as that's set up for minimum 4 bytes per item.
   428     uuid.clock_seq_hi_and_reserved = (aClockSeq & 0x3F00) >> 8;
   377     CArrayFixFlat<TUint8> *node = new (ELeave) CArrayFixFlat<TUint8>(6);
   429     uuid.clock_seq_hi_and_reserved |= 0x80;
   378     CleanupStack::PushL(node);
   430    
   379 
       
   380     // The rest of the function is mapping the 64, 32 and 16 bit numbers to 8 bit numbers
       
   381     // while losing as little data as possible.
       
   382 
       
   383     TUint64 mask = 0xFF0000000000;
   431     TUint64 mask = 0xFF0000000000;
   384     for(TInt i=0; i<=6; ++i)
   432     for(TInt i=0; i<=6; ++i)
   385         {
   433         {
   386         TInt64 temp = aNodeValue & mask;
   434         TInt64 temp = aNodeValue & mask;
   387         temp >>= ((5-i)*8);
   435         temp >>= ((5-i)*8);
   388         node->AppendL(temp);
   436         uuid.node[i] = temp;
   389         mask = mask >> 8;
   437         mask = mask >> 8;
   390         }
   438         }
   391 
   439 
   392     TBuf8<16> rawOutput;
   440     //md5 context   
   393 
   441     MD5_CTX context;
   394     rawOutput.Append( (time_low  & 0xFF000000) >> 24 );
       
   395     rawOutput.Append( (time_low  & 0x00FF0000) >> 16 );
       
   396     rawOutput.Append( (time_low  & 0x0000FF00) >> 8 );
       
   397     rawOutput.Append( (time_low  & 0x000000FF) );
       
   398 
       
   399     rawOutput.Append( (time_mid  & 0xFF00) >> 8 );
       
   400     rawOutput.Append( (time_mid  & 0x00FF) );
       
   401 
       
   402     rawOutput.Append( (time_high & 0xFF00) >> 8 );
       
   403     rawOutput.Append( (time_high & 0x00FF) );
       
   404 
       
   405     rawOutput.Append( clock_seq_low );
       
   406     rawOutput.Append( clock_seq_high );
       
   407 
       
   408     for(TInt i=0; i<6; ++i)
       
   409         {
       
   410         rawOutput.Append( node->At(i) );
       
   411         }
       
   412     CleanupStack::PopAndDestroy(); // node
       
   413     
       
   414     TUint8 digest[16];
       
   415     HBufC8* resultBuf = rawOutput.AllocLC();
       
   416     TPtr8 resultBufPtr = resultBuf->Des();
       
   417     TUint length = resultBufPtr.Length();
       
   418     
       
   419     // Create a new buffer to provide space for '\0'
       
   420     HBufC8* newBuf = HBufC8::NewLC( length + 1 );//+1 space for '\0'
       
   421     TPtr8 newBufPtr = newBuf->Des();
       
   422     newBufPtr.Copy(resultBufPtr);
       
   423     
       
   424     // Appends a zero terminator onto the end of this descriptor's data
       
   425     // and returns a pointer to the data.
       
   426     char* chPtrTemp = ( char*)newBufPtr.PtrZ();
       
   427     char* chPtr = ( char*) User::AllocL( length + 1 );
       
   428     strcpy( chPtr , chPtrTemp );
       
   429     
       
   430     //md5 context
       
   431     MD5_CTX* context = new MD5_CTX();
       
   432     //initialize the context
   442     //initialize the context
   433     MD5_Init(context);
   443     MD5_Init(&context);
   434     //Append a string to the message
   444     //Append a string to the message
   435     MD5_Update(context, chPtr, length );
   445     MD5_Update(&context, &uuid, sizeof(uuid) );
   436     //Finish the message and return the digest.
   446     //Finish the message and return the digest.
   437     MD5_Final(digest, context );
   447     MD5_Final(hash, &context );
   438     
       
   439     // Add the version field in the msb 4 bits. The value of version is 3.
   448     // Add the version field in the msb 4 bits. The value of version is 3.
   440     digest[6] = digest[6] & 0x0F;
   449     hash[6] = hash[6] & 0x0F;
   441     digest[6] |= (3 << 4);
   450     hash[6] |= (3 << 4);
   442     
   451     
   443     //Add the variant field in the msb 2 bits. The value of variant is 2.
   452     //Add the variant field in the msb 2 bits. The value of variant is 2.
   444     digest[9] = digest[9] & 0x3F;
   453     hash[8] = hash[8] & 0x3F;
   445     digest[9] |= 0x80;
   454     hash[8] |= 0x80;
   446     
   455            
   447     delete chPtr;
       
   448     delete context;
       
   449     CleanupStack::PopAndDestroy( newBuf );
       
   450     CleanupStack::PopAndDestroy( resultBuf );
       
   451     TBuf8<36> output;
   456     TBuf8<36> output;
   452     TInt i;
   457     TInt i;
   453     for(i=0; i<16; ++i)
   458     for(i=0; i<16; ++i)
   454         {
   459       {
   455         output.Append( ConvertToCharacterL( FirstFourBits( digest[i] ) ) ); 
   460       output.Append( ConvertToCharacterL( FirstFourBits( hash[i] ) ) ); 
   456         output.Append( ConvertToCharacterL( LastFourBits( digest[i] ) ) );
   461       output.Append( ConvertToCharacterL( LastFourBits( hash[i] ) ) );
   457         if(i == 3 || i == 5 || i == 7 ||i == 9)
   462       if(i == 3 || i == 5 || i == 7 ||i == 9)
   458             {
   463           {
   459             output.Append( '-' );
   464           output.Append( '-' );
   460             }
   465           }
   461         }
   466       }
   462     HBufC8* md5ResultBuf = output.AllocLC();
   467     HBufC8* retBuf = output.AllocLC();
   463     
   468     
   464     TRACE_EXIT_POINT;
   469     TRACE_EXIT_POINT;
   465     return md5ResultBuf;
   470     return retBuf;
       
   471     
   466     }
   472     }
   467 
   473 
   468 // -----------------------------------------------------------------------------
   474 // -----------------------------------------------------------------------------
   469 // CCalenInterimUtils2Impl::ConvertToCharacterL()
   475 // CCalenInterimUtils2Impl::ConvertToCharacterL()
   470 // Converts from a number between 0-15 to a hexadecimal character representation.
   476 // Converts from a number between 0-15 to a hexadecimal character representation.
   559 // Checks to see if Meeting Request Viewer functionality
   565 // Checks to see if Meeting Request Viewer functionality
   560 // is enabled and an implementation is available to use
   566 // is enabled and an implementation is available to use
   561 // (other items were commented in a header).
   567 // (other items were commented in a header).
   562 // -----------------------------------------------------------------------------
   568 // -----------------------------------------------------------------------------
   563 //
   569 //
   564 TBool CCalenInterimUtils2Impl::MRViewersEnabledL(TBool /*aForceCheck*/)
   570 TBool CCalenInterimUtils2Impl::MRViewersEnabledL(TBool aForceCheck)
   565     {
   571     {
   566     TRACE_ENTRY_POINT;
   572     TRACE_ENTRY_POINT;
   567     // Need to implement it once we have meeting request viewer in 10.1
   573     if( aForceCheck || iMrEnabledCheck )
   568     TRACE_EXIT_POINT;
   574         {
   569     return false;    
   575 		iMrEnabled = EFalse;
       
   576 		iMrEnabledCheck = EFalse;
       
   577 
       
   578         PIM_TRAPD_HANDLE( DoMRViewersEnabledL() );
       
   579         }
       
   580         
       
   581     TRACE_EXIT_POINT;
       
   582     return iMrEnabled;    
   570     }
   583     }
   571 // -----------------------------------------------------------------------------
   584 // -----------------------------------------------------------------------------
   572 // CCalenInterimUtils2Impl::DoMRViewersEnabledL()
   585 // CCalenInterimUtils2Impl::DoMRViewersEnabledL()
   573 // Checks to see if Meeting Request Viewer functionality
   586 // Checks to see if Meeting Request Viewer functionality
   574 // is enabled and an implementation is available to use
   587 // is enabled and an implementation is available to use
   576 // -----------------------------------------------------------------------------
   589 // -----------------------------------------------------------------------------
   577 //
   590 //
   578 void CCalenInterimUtils2Impl::DoMRViewersEnabledL()
   591 void CCalenInterimUtils2Impl::DoMRViewersEnabledL()
   579     {
   592     {
   580     TRACE_ENTRY_POINT;
   593     TRACE_ENTRY_POINT;
   581 		// Need to implement it once we have meeting request viewer in 10.1
   594 
   582     TRACE_EXIT_POINT;
   595     // We ignore any leaves because iMrEnabled and iMrEnabledCheck are already set to
       
   596     // EFalse, so if the function leaves it will return EFalse this time and any future
       
   597     // calls will not force a check (unless aForceCheck is ETrue).
       
   598     if (FeatureManager::FeatureSupported(KFeatureIdMeetingRequestSupport))
       
   599         {
       
   600         // Full meeting request solution
       
   601         // As long as we have at least one mailbox we can return true
       
   602         CMRMailboxUtils *mbUtils = CMRMailboxUtils::NewL();
       
   603         CleanupStack::PushL( mbUtils );
       
   604 
       
   605                 RArray<CMRMailboxUtils::TMailboxInfo> mailboxes;
       
   606                 CleanupClosePushL(mailboxes);
       
   607                 mbUtils->ListMailBoxesL(mailboxes);
       
   608                 if(mailboxes.Count() > 0)
       
   609                     {
       
   610                     iMrEnabled = ETrue; // && 1 mailbox
       
   611                     }
       
   612 
       
   613         CleanupStack::PopAndDestroy(); // mailboxes
       
   614         CleanupStack::PopAndDestroy(); // mbUtils
       
   615         }
       
   616      else
       
   617         {
       
   618         if (FeatureManager::FeatureSupported(KFeatureIdMeetingRequestEnabler))
       
   619             {
       
   620     		// Meeting request enablers solution
       
   621     		//Check for:
       
   622     		//	At least one mailbox exists on the terminal
       
   623     		//	At least one MRViewer implementation, with an id matching a mailbox,
       
   624     		    //	exists on the terminal
       
   625     		    //	At least one MRUtils implementation exists on the terminal
       
   626     		    CMRMailboxUtils *mbUtils = CMRMailboxUtils::NewL();
       
   627     		    CleanupStack::PushL( mbUtils );
       
   628 
       
   629                 RArray<CMRMailboxUtils::TMailboxInfo> mailboxes;
       
   630                 CleanupClosePushL(mailboxes);
       
   631 
       
   632                 mbUtils->ListMailBoxesL(mailboxes);
       
   633                 if(mailboxes.Count() > 0)
       
   634                     {
       
   635                     RImplInfoPtrArrayOwn implArray;
       
   636                      CleanupClosePushL( implArray );
       
   637 
       
   638                      //Check for a MRViewers Implementation
       
   639                      const TUid mrViewersIface = {KMRViewersInterfaceUID};
       
   640                      REComSession::ListImplementationsL(mrViewersIface, implArray );
       
   641                      if ( implArray.Count() > 0 )
       
   642                          {
       
   643                          // MRViewers implementations exist.  We need to see if any are
       
   644                          // associated with an existing mailbox
       
   645                          TBool mrImplMatchesMailbox = EFalse;
       
   646                          for (TInt i=0; i<implArray.Count(); ++i)
       
   647                              {
       
   648                              for(TInt j=0; j<mailboxes.Count(); ++j)
       
   649                                  {
       
   650                                  TBuf16<KMaxUidName> mbName;
       
   651                                  CnvUtfConverter::ConvertToUnicodeFromUtf8( mbName, implArray[i]->DataType() );
       
   652                                  if(mailboxes[j].iMtmUid.Name().CompareF(mbName) == 0)
       
   653                                      {
       
   654                                     mrImplMatchesMailbox = ETrue;
       
   655                                     //One match is enough for this decision to be true
       
   656                                     break;
       
   657                                     }
       
   658                                  }
       
   659                              if (mrImplMatchesMailbox)
       
   660                                  {
       
   661                                  break;
       
   662                                  }
       
   663                              }
       
   664 
       
   665                          // Reset the viewer implementation array.  This will be reused
       
   666                          // if we need to check for mr utils implementations
       
   667                          implArray.ResetAndDestroy();
       
   668 
       
   669                          if (mrImplMatchesMailbox)
       
   670                              {
       
   671                              // We have at least one MRViewer implementation with an associated
       
   672                              // mailbox.  Check for a matching MR utils implementation
       
   673                              const TUid mrUtilsIface = {KMRUtilsInterfaceUID};
       
   674                              REComSession::ListImplementationsL(mrUtilsIface, implArray );
       
   675                              if (implArray.Count() > 0)
       
   676                                  {
       
   677                                  // Meeting request functionality is available on this device
       
   678                                  iMrEnabled = ETrue;
       
   679                                  }
       
   680                              }
       
   681 
       
   682                          }
       
   683                       CleanupStack::PopAndDestroy(); // implArray
       
   684                       }
       
   685 
       
   686                 CleanupStack::PopAndDestroy(); // mailboxes
       
   687                 CleanupStack::PopAndDestroy(); // mbUtils
       
   688                 }            
       
   689             }
   583     }
   690     }
   584 
   691 
   585 // -----------------------------------------------------------------------------
   692 // -----------------------------------------------------------------------------
   586 // CCalenInterimUtils2Impl::HasTimeOrDateChangedL()
   693 // CCalenInterimUtils2Impl::HasTimeOrDateChangedL()
   587 // Checks to see if the date or time has changed from the given entry to the
   694 // Checks to see if the date or time has changed from the given entry to the
   624     if (FeatureManager::FeatureSupported(KFeatureIdMeetingRequestEnabler) ||
   731     if (FeatureManager::FeatureSupported(KFeatureIdMeetingRequestEnabler) ||
   625         FeatureManager::FeatureSupported(KFeatureIdMeetingRequestSupport))
   732         FeatureManager::FeatureSupported(KFeatureIdMeetingRequestSupport))
   626         {
   733         {
   627         if( IsMeetingRequestL(aEntry) && aEntry.PhoneOwnerL() == NULL )
   734         if( IsMeetingRequestL(aEntry) && aEntry.PhoneOwnerL() == NULL )
   628             {
   735             {
   629             // Need to implement it once we have meeting request viewer in 10.1
   736             CMRMailboxUtils *mbUtils = CMRMailboxUtils::NewL();
       
   737             CleanupStack::PushL( mbUtils );
       
   738             mbUtils->SetPhoneOwnerL( aEntry );
       
   739             CleanupStack::PopAndDestroy(); // mbUtils
   630             }
   740             }
   631         }
   741         }
   632     FeatureManager::UnInitializeLib();
   742     FeatureManager::UnInitializeLib();
   633     
   743     
   634     TRACE_EXIT_POINT;
   744     TRACE_EXIT_POINT;