--- a/calendarengines/caleninterimutils/src/CalenInterimUtils2Impl.cpp Tue Aug 31 15:13:43 2010 +0300
+++ b/calendarengines/caleninterimutils/src/CalenInterimUtils2Impl.cpp Wed Sep 01 12:32:31 2010 +0100
@@ -32,7 +32,9 @@
#include <etelmm.h>
#include <e32math.h>
#include <calrrule.h>
+#include <cmrmailboxutils.h>
#include <featmgr.h>
+#include <MeetingRequestUids.hrh>
#include <ecom/ecom.h>
#include <utf.h>
#include <openssl/md5.h>
@@ -43,6 +45,13 @@
#include "CalenEcomWatcher.h" // Watches for ECOM registry changes
// CONSTANTS
+
+/* set the following to the number of 100ns ticks of the actual
+ resolution of your system's clock.
+ 800MHZ means 1s->800*(10^6) clock cycles
+ 100ns->80 clock cycles*/
+const TUint16 UUIDS_PER_TICK = 80;
+
/// Unnamed namespace for local definitions
namespace {
@@ -51,8 +60,7 @@
#endif
const TInt KImeiLength = 15; // 15 chars from left of imei
-
- const TInt KAsciiFirstNumber = 48; // ASCII character 48 = '0'.
+ const TInt KAsciiFirstNumber = 48; // ASCII character 48 = '0'.
const TInt KAsciiFirstLowercaseLetter = 97; // ASCII character 97 = 'a'.
} // namespace
@@ -88,6 +96,9 @@
{
TRACE_ENTRY_POINT;
+ iMrEnabledCheck = ETrue;
+ iMrEnabled = EFalse;
+ iInited = EFalse;
TRACE_EXIT_POINT;
}
@@ -274,15 +285,17 @@
// http://www.webdav.org/specs/draft-leach-uuids-guids-01.txt
// Number of 100ns ticks since Oct 15 1582.
- TInt64 timeStamp = GetTicksFromGregorianCalendarStartL();
-
+ TInt64 timeStamp;
+ GetSystemTime(timeStamp);
+
// This differs slightly from the spec in that the clock sequence is just a pseudo-random number.
- TUint32 clockSeq = Math::Random();
- // IMEI is read the first time this is called, and stored for subsequent calls.
- if(!iImeiNode)
- {
- iImeiNode = GetImeiAsNodeValueL();
- }
+ TUint32 clockSeq = Math::Random();
+
+ // IMEI is read the first time this is called, and stored for subsequent calls.
+ if(!iImeiNode)
+ {
+ iImeiNode = GetImeiAsNodeValueL();
+ }
HBufC8* resultBuf = DoCreateUidLC(clockSeq, timeStamp, iImeiNode);
CleanupStack::Pop(resultBuf);
@@ -308,7 +321,46 @@
TTimeIntervalMicroSeconds msDifference = timeNow.MicroSecondsFrom(gregorianStart);
TRACE_EXIT_POINT;
- return msDifference.Int64() * 10; // * 10 to convert from micro sec (==1000 ns) count to 100ns count.
+ return ( timeNow.Int64() + msDifference.Int64() ) * 10; // * 10 to convert from micro sec (==1000 ns) count to 100ns count.
+ }
+
+// -----------------------------------------------------------------------------
+// CCalenInterimUtils2Impl::GetSystemTime()
+// This function returns the system time.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCalenInterimUtils2Impl::GetSystemTime(TInt64& aTimeStamp)
+ {
+ TRACE_ENTRY_POINT;
+
+ if (!iInited)
+ {
+ aTimeStamp = GetTicksFromGregorianCalendarStartL();
+ iThisTick = UUIDS_PER_TICK;
+ iInited = ETrue;
+ }
+ for( ; ; )
+ {
+ aTimeStamp = GetTicksFromGregorianCalendarStartL();
+ //if clock reading changed since last UUID generated...
+ if( iTimeLast != aTimeStamp )
+ {
+ //reset count of uuids gen'd with this clock reading
+ iThisTick = 0;
+ iTimeLast = aTimeStamp;
+ break;
+ }
+ if( iThisTick < UUIDS_PER_TICK )
+ {
+ iThisTick++;
+ break;
+ }
+ }
+ //add the count of uuids to low order bits of the clock reading
+ aTimeStamp += iThisTick;
+
+ TRACE_EXIT_POINT;
}
// -----------------------------------------------------------------------------
@@ -365,104 +417,58 @@
TRACE_ENTRY_POINT;
// The roast beef of the algorithm. Does all the shifting about as described in the web draft.
- TUint32 time_low = aTimeStamp & 0xFFFFFFFF;
- TUint16 time_mid = (aTimeStamp >> 32) & 0xFFFF;
- TUint16 time_high = (aTimeStamp >> 48) & 0x0FFF;
- time_high |= (1 << 12);
- TUint8 clock_seq_low = aClockSeq & 0xFF;
- TUint8 clock_seq_high = (aClockSeq & 0x3F00) >> 8;
- clock_seq_high |= 0x80;
-
- // Can't use RArray as that's set up for minimum 4 bytes per item.
- CArrayFixFlat<TUint8> *node = new (ELeave) CArrayFixFlat<TUint8>(6);
- CleanupStack::PushL(node);
-
- // The rest of the function is mapping the 64, 32 and 16 bit numbers to 8 bit numbers
- // while losing as little data as possible.
-
+ SUuid uuid;
+ TUint8 hash[16];
+
+ uuid.time_low = aTimeStamp & 0xFFFFFFFF;
+ uuid.time_mid = (aTimeStamp >> 32) & 0xFFFF;
+ uuid.time_high_and_version = (aTimeStamp >> 48) & 0x0FFF;
+ uuid.time_high_and_version |= (1 << 12);
+ uuid.clock_seq_low = aClockSeq & 0xFF;
+ uuid.clock_seq_hi_and_reserved = (aClockSeq & 0x3F00) >> 8;
+ uuid.clock_seq_hi_and_reserved |= 0x80;
+
TUint64 mask = 0xFF0000000000;
for(TInt i=0; i<=6; ++i)
{
TInt64 temp = aNodeValue & mask;
temp >>= ((5-i)*8);
- node->AppendL(temp);
+ uuid.node[i] = temp;
mask = mask >> 8;
}
- TBuf8<16> rawOutput;
-
- rawOutput.Append( (time_low & 0xFF000000) >> 24 );
- rawOutput.Append( (time_low & 0x00FF0000) >> 16 );
- rawOutput.Append( (time_low & 0x0000FF00) >> 8 );
- rawOutput.Append( (time_low & 0x000000FF) );
-
- rawOutput.Append( (time_mid & 0xFF00) >> 8 );
- rawOutput.Append( (time_mid & 0x00FF) );
-
- rawOutput.Append( (time_high & 0xFF00) >> 8 );
- rawOutput.Append( (time_high & 0x00FF) );
-
- rawOutput.Append( clock_seq_low );
- rawOutput.Append( clock_seq_high );
-
- for(TInt i=0; i<6; ++i)
- {
- rawOutput.Append( node->At(i) );
- }
- CleanupStack::PopAndDestroy(); // node
-
- TUint8 digest[16];
- HBufC8* resultBuf = rawOutput.AllocLC();
- TPtr8 resultBufPtr = resultBuf->Des();
- TUint length = resultBufPtr.Length();
-
- // Create a new buffer to provide space for '\0'
- HBufC8* newBuf = HBufC8::NewLC( length + 1 );//+1 space for '\0'
- TPtr8 newBufPtr = newBuf->Des();
- newBufPtr.Copy(resultBufPtr);
-
- // Appends a zero terminator onto the end of this descriptor's data
- // and returns a pointer to the data.
- char* chPtrTemp = ( char*)newBufPtr.PtrZ();
- char* chPtr = ( char*) User::AllocL( length + 1 );
- strcpy( chPtr , chPtrTemp );
-
- //md5 context
- MD5_CTX* context = new MD5_CTX();
+ //md5 context
+ MD5_CTX context;
//initialize the context
- MD5_Init(context);
+ MD5_Init(&context);
//Append a string to the message
- MD5_Update(context, chPtr, length );
+ MD5_Update(&context, &uuid, sizeof(uuid) );
//Finish the message and return the digest.
- MD5_Final(digest, context );
-
+ MD5_Final(hash, &context );
// Add the version field in the msb 4 bits. The value of version is 3.
- digest[6] = digest[6] & 0x0F;
- digest[6] |= (3 << 4);
+ hash[6] = hash[6] & 0x0F;
+ hash[6] |= (3 << 4);
//Add the variant field in the msb 2 bits. The value of variant is 2.
- digest[9] = digest[9] & 0x3F;
- digest[9] |= 0x80;
-
- delete chPtr;
- delete context;
- CleanupStack::PopAndDestroy( newBuf );
- CleanupStack::PopAndDestroy( resultBuf );
+ hash[8] = hash[8] & 0x3F;
+ hash[8] |= 0x80;
+
TBuf8<36> output;
TInt i;
for(i=0; i<16; ++i)
- {
- output.Append( ConvertToCharacterL( FirstFourBits( digest[i] ) ) );
- output.Append( ConvertToCharacterL( LastFourBits( digest[i] ) ) );
- if(i == 3 || i == 5 || i == 7 ||i == 9)
- {
- output.Append( '-' );
- }
- }
- HBufC8* md5ResultBuf = output.AllocLC();
+ {
+ output.Append( ConvertToCharacterL( FirstFourBits( hash[i] ) ) );
+ output.Append( ConvertToCharacterL( LastFourBits( hash[i] ) ) );
+ if(i == 3 || i == 5 || i == 7 ||i == 9)
+ {
+ output.Append( '-' );
+ }
+ }
+ HBufC8* retBuf = output.AllocLC();
TRACE_EXIT_POINT;
- return md5ResultBuf;
+ return retBuf;
+
}
// -----------------------------------------------------------------------------
@@ -561,12 +567,19 @@
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
-TBool CCalenInterimUtils2Impl::MRViewersEnabledL(TBool /*aForceCheck*/)
+TBool CCalenInterimUtils2Impl::MRViewersEnabledL(TBool aForceCheck)
{
TRACE_ENTRY_POINT;
- // Need to implement it once we have meeting request viewer in 10.1
+ if( aForceCheck || iMrEnabledCheck )
+ {
+ iMrEnabled = EFalse;
+ iMrEnabledCheck = EFalse;
+
+ PIM_TRAPD_HANDLE( DoMRViewersEnabledL() );
+ }
+
TRACE_EXIT_POINT;
- return false;
+ return iMrEnabled;
}
// -----------------------------------------------------------------------------
// CCalenInterimUtils2Impl::DoMRViewersEnabledL()
@@ -578,8 +591,102 @@
void CCalenInterimUtils2Impl::DoMRViewersEnabledL()
{
TRACE_ENTRY_POINT;
- // Need to implement it once we have meeting request viewer in 10.1
- TRACE_EXIT_POINT;
+
+ // We ignore any leaves because iMrEnabled and iMrEnabledCheck are already set to
+ // EFalse, so if the function leaves it will return EFalse this time and any future
+ // calls will not force a check (unless aForceCheck is ETrue).
+ if (FeatureManager::FeatureSupported(KFeatureIdMeetingRequestSupport))
+ {
+ // Full meeting request solution
+ // As long as we have at least one mailbox we can return true
+ CMRMailboxUtils *mbUtils = CMRMailboxUtils::NewL();
+ CleanupStack::PushL( mbUtils );
+
+ RArray<CMRMailboxUtils::TMailboxInfo> mailboxes;
+ CleanupClosePushL(mailboxes);
+ mbUtils->ListMailBoxesL(mailboxes);
+ if(mailboxes.Count() > 0)
+ {
+ iMrEnabled = ETrue; // && 1 mailbox
+ }
+
+ CleanupStack::PopAndDestroy(); // mailboxes
+ CleanupStack::PopAndDestroy(); // mbUtils
+ }
+ else
+ {
+ if (FeatureManager::FeatureSupported(KFeatureIdMeetingRequestEnabler))
+ {
+ // Meeting request enablers solution
+ //Check for:
+ // At least one mailbox exists on the terminal
+ // At least one MRViewer implementation, with an id matching a mailbox,
+ // exists on the terminal
+ // At least one MRUtils implementation exists on the terminal
+ CMRMailboxUtils *mbUtils = CMRMailboxUtils::NewL();
+ CleanupStack::PushL( mbUtils );
+
+ RArray<CMRMailboxUtils::TMailboxInfo> mailboxes;
+ CleanupClosePushL(mailboxes);
+
+ mbUtils->ListMailBoxesL(mailboxes);
+ if(mailboxes.Count() > 0)
+ {
+ RImplInfoPtrArrayOwn implArray;
+ CleanupClosePushL( implArray );
+
+ //Check for a MRViewers Implementation
+ const TUid mrViewersIface = {KMRViewersInterfaceUID};
+ REComSession::ListImplementationsL(mrViewersIface, implArray );
+ if ( implArray.Count() > 0 )
+ {
+ // MRViewers implementations exist. We need to see if any are
+ // associated with an existing mailbox
+ TBool mrImplMatchesMailbox = EFalse;
+ for (TInt i=0; i<implArray.Count(); ++i)
+ {
+ for(TInt j=0; j<mailboxes.Count(); ++j)
+ {
+ TBuf16<KMaxUidName> mbName;
+ CnvUtfConverter::ConvertToUnicodeFromUtf8( mbName, implArray[i]->DataType() );
+ if(mailboxes[j].iMtmUid.Name().CompareF(mbName) == 0)
+ {
+ mrImplMatchesMailbox = ETrue;
+ //One match is enough for this decision to be true
+ break;
+ }
+ }
+ if (mrImplMatchesMailbox)
+ {
+ break;
+ }
+ }
+
+ // Reset the viewer implementation array. This will be reused
+ // if we need to check for mr utils implementations
+ implArray.ResetAndDestroy();
+
+ if (mrImplMatchesMailbox)
+ {
+ // We have at least one MRViewer implementation with an associated
+ // mailbox. Check for a matching MR utils implementation
+ const TUid mrUtilsIface = {KMRUtilsInterfaceUID};
+ REComSession::ListImplementationsL(mrUtilsIface, implArray );
+ if (implArray.Count() > 0)
+ {
+ // Meeting request functionality is available on this device
+ iMrEnabled = ETrue;
+ }
+ }
+
+ }
+ CleanupStack::PopAndDestroy(); // implArray
+ }
+
+ CleanupStack::PopAndDestroy(); // mailboxes
+ CleanupStack::PopAndDestroy(); // mbUtils
+ }
+ }
}
// -----------------------------------------------------------------------------
@@ -626,7 +733,10 @@
{
if( IsMeetingRequestL(aEntry) && aEntry.PhoneOwnerL() == NULL )
{
- // Need to implement it once we have meeting request viewer in 10.1
+ CMRMailboxUtils *mbUtils = CMRMailboxUtils::NewL();
+ CleanupStack::PushL( mbUtils );
+ mbUtils->SetPhoneOwnerL( aEntry );
+ CleanupStack::PopAndDestroy(); // mbUtils
}
}
FeatureManager::UnInitializeLib();