--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javaextensions/wma/mms/pushplugin/src.s60/s60mmsserverconnection.cpp Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,372 @@
+/*
+* Copyright (c) 2008 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:
+ *
+*/
+
+
+#include "logger.h"
+#include "pushexception.h"
+#include "pusherrorcodes.h"
+#include "s60commonutils.h"
+#include "connectionlistener.h"
+#include "s60mmsserverconnection.h"
+#include "mmsserverconnectionfactory.h"
+
+_LIT16(KThreadName, "MmsServerThread");
+const TInt KAppIdStartIndex = 7 ;
+
+using namespace std;
+using namespace java::util;
+
+namespace java
+{
+namespace wma
+{
+
+OS_EXPORT S60MmsServerConnection::S60MmsServerConnection(const wstring& aUri,
+ const wstring& aFilter)
+ :CActive(EPriorityStandard), mUri(aUri), mFilter(aFilter),
+ mActiveConnection(false), mIsAppLaunched(false),mListener(0)
+
+{
+ JELOG2(EWMA);
+ mAppId = aUri.substr(KAppIdStartIndex); // "mms://:"
+ LOG1(EWMA,EInfo,"created MmsServerConnection on ID %S", mAppId.c_str());
+ mOpenMonitor = java::util::Monitor::createMonitor();
+}
+
+ServerConnection* MmsServerConnection::getServerConnection(const wstring& aUri,
+ const wstring& aFilter)
+{
+ JELOG2(EWMA);
+ S60MmsServerConnection* mmsConn = new S60MmsServerConnection(aUri,aFilter);
+ return mmsConn;
+}
+
+S60MmsServerConnection::~S60MmsServerConnection()
+{
+ JELOG2(EWMA);
+ delete mOpenMonitor;
+}
+
+OS_EXPORT void S60MmsServerConnection::setOpen()
+{
+ JELOG2(EWMA);
+ mIsAppLaunched = true;
+ MmsServerConnectionFactory::getFactory().setPendingMsgFlag(
+ mUri, false);
+}
+
+OS_EXPORT void S60MmsServerConnection::open(ConnectionListener* aListener)
+{
+ JELOG2(EWMA);
+ mListener = aListener;
+ if (!mIsAppLaunched)
+ {
+ TBuf<50> threadName;
+ threadName.Append(KThreadName);
+ threadName.Append('_');
+ TTime time;
+ time.HomeTime();
+ threadName.AppendNum(time.Int64());
+ mState = EReceivingMessageForNotify;
+ int error = mThread.Create(threadName,
+ reinterpret_cast<TThreadFunction>(listenThread),
+ KDefaultStackSize, NULL, this);
+ if (error != KErrNone)
+ {
+ ELOG1(EWMA,"S60MmsServerConnection Thread create failed : %d",error);
+ string errTxt("ERROR!!! Open Failed");
+ throw PushException(COMMON_SRV_CONN_PLUGIN_ERROR, errTxt, __FILE__,
+ __FUNCTION__, __LINE__);
+ }
+
+ mThread.Resume();
+ mOpenMonitor->wait();
+ if (mError != KErrNone)
+ {
+ std::string errTxt("ERROR!!! Open Failed");
+ throw PushException(COMMON_SRV_CONN_PLUGIN_ERROR, errTxt, __FILE__,
+ __FUNCTION__, __LINE__);
+ }
+ mActiveConnection = true;
+ }
+}
+
+void S60MmsServerConnection::InitializeL()
+{
+ JELOG2(EWMA);
+ mMmsApplicationAdapter = CMmsApplicationAdapter::NewL();
+ mSession = CMsvSession::OpenSyncL(*this);
+ mApplicationId = S60CommonUtils::wstringToDes(mAppId.c_str());
+ TMsvId folderId;
+ mMmsApplicationAdapter->RegisterL(*mApplicationId, folderId);
+ TMsvId tmsvId = mMmsApplicationAdapter->FolderIdL(*mApplicationId);
+ if (tmsvId != KErrNone)
+ {
+ // get the
+ mClientEntry = mSession->GetEntryL(tmsvId);
+ // Add listener to the created entry for that application Id
+ mClientEntry->AddObserverL(*this);
+ }
+ int error = pthread_mutex_init(&mMutex, 0);
+ if (error == 0)
+ {
+ error = pthread_cond_init(&mCondVar, 0);
+ }
+ if (0 != error)
+ {
+ User::Leave(error);
+ }
+}
+
+int S60MmsServerConnection::listenThread(S60MmsServerConnection* aMmsSrvConn)
+{
+ JELOG2(EWMA);
+ int error;
+ CTrapCleanup* tc = CTrapCleanup::New();
+ // As there is no possibility of active scheduler being installed to this
+ // thread prior to this , there is no need for any checks.
+ CActiveScheduler* activeScheduler = new CActiveScheduler();
+ CActiveScheduler::Install(activeScheduler);
+ CActiveScheduler::Add(aMmsSrvConn);
+ TRAP(error, aMmsSrvConn->InitializeL());
+ if (error != KErrNone)
+ {
+ ELOG1(EWMA, "error Creating CRetrieveMobilePhoneBroadcastIdList =%d",
+ error);
+ aMmsSrvConn->mError = error;
+ (aMmsSrvConn->mOpenMonitor)->notify();
+ delete activeScheduler;
+ delete tc;
+ (aMmsSrvConn->mThread).Close();
+ return 0;
+ }
+ aMmsSrvConn->iStatus = KRequestPending;
+ aMmsSrvConn->SetActive();
+ (aMmsSrvConn->mOpenMonitor)->notify();
+ activeScheduler->Start();
+ delete activeScheduler;
+ delete tc;
+ return 0;
+}
+
+void S60MmsServerConnection::HandleSessionEventL(TMsvSessionEvent,
+ TAny*, TAny*, TAny*)
+{
+
+}
+
+void S60MmsServerConnection::HandleEntryEventL(TMsvEntryEvent aEvent,
+ TAny* aArg1, TAny*, TAny*)
+{
+ JELOG2(EWMA);
+ if (mIsAppLaunched)
+ {
+ // midlet is already running, Server connection can read the messages
+ return;
+ }
+
+ switch (aEvent)
+ {
+ case MMsvSessionObserver::EMsvEntriesChanged:
+ case MMsvEntryObserver::EMsvEntryChanged:
+ {
+ CMsvEntrySelection* msvEntrySelection =
+ static_cast<CMsvEntrySelection*>(aArg1);
+ //Process each entry, one at a time.
+ TInt count = msvEntrySelection->Count();
+ CleanupStack::PushL(msvEntrySelection);
+ for (TInt i = 0; i < count; i++)
+ {
+ TMsvId msvId = msvEntrySelection->At(i);
+ CheckForValidMessageAndPushL(msvId);
+
+ }// end of for loop
+ CleanupStack::Pop(msvEntrySelection); // entries
+ }
+ break;
+ default:
+ // Nothing to do
+ break;
+ }
+}
+//--------------------------------------------------------------------------------------------
+// CheckForValidMessageAndPush
+//--------------------------------------------------------------------------------------------
+void S60MmsServerConnection::CheckForValidMessageAndPushL(TMsvId aMsgId)
+{
+ JELOG2(EWMA);
+ if (!IsMmsReadyToReadL(aMsgId))
+ {
+
+ return; // message is not reday
+ }
+
+ TPtrC appId = mMmsApplicationAdapter->ApplicationIdL(aMsgId);
+ if (mApplicationId->Compare(appId) == 0)
+ {
+ MmsRequestCompleted();
+ }
+}
+
+TBool S60MmsServerConnection::IsMmsReadyToReadL(TMsvId aMsvId)
+{
+ JELOG2(EWMA);
+ TBool error = EFalse;
+ CMsvEntry* csvEntry = mSession->GetEntryL(aMsvId);
+ TMsvEntry tmsvEntry = csvEntry->Entry();
+
+ if (tmsvEntry.iMtm != KUidMsgTypeMultimedia)
+ {
+ delete csvEntry;
+ csvEntry = NULL;
+ }
+ // Check if the entry is ready to be read
+ else if (!tmsvEntry.InPreparation())
+ { //Not in preparation
+ error = ETrue;
+ delete csvEntry;
+ csvEntry = NULL;
+ }
+ return error;
+}
+
+void S60MmsServerConnection::DoCancel()
+{
+ JELOG2(EWMA);
+ // Only cancel the appropriate asynchronous request
+ TRequestStatus *status = &iStatus;
+ mThread.RequestComplete(status, KErrCancel);
+}
+
+OS_EXPORT wstring S60MmsServerConnection::getUri() const
+{
+ JELOG2(EWMA);
+ return mUri;
+}
+
+OS_EXPORT void S60MmsServerConnection::setFilter(const std::wstring& aFilter)
+{
+ JELOG2(EWMA);
+ mFilter = aFilter;
+}
+
+OS_EXPORT wstring S60MmsServerConnection::getFilter() const
+{
+ JELOG2(EWMA);
+ return mFilter;
+}
+
+void S60MmsServerConnection::close()
+{
+ JELOG2(EWMA);
+ // the close and RunL are synchronized to make it SMP safe.
+ if (mActiveConnection)
+ {
+ pthread_mutex_lock(&mMutex);
+ mActiveConnection = false;
+ mState = ENotifyingClose;
+ MmsRequestCompleted();
+ pthread_cond_wait(&mCondVar, &mMutex);
+ pthread_mutex_unlock(&mMutex);
+ pthread_mutex_destroy(&mMutex);
+ pthread_cond_destroy(&mCondVar);
+ }
+ mIsAppLaunched = false;
+ delete mApplicationId;
+ mApplicationId = 0;
+}
+
+TInt S60MmsServerConnection::RunError(TInt aError)
+{
+ JELOG2(EWMA);
+ mListener->error(mUri, aError, "Error Receiving MultiMedia Message");
+ pthread_cond_signal(&mCondVar);
+ pthread_mutex_unlock(&mMutex);
+ return KErrNone;
+}
+
+void S60MmsServerConnection::RunL()
+{
+ JELOG2(EWMA);
+ pthread_mutex_lock(&mMutex);
+ switch (mState)
+ {
+ case EReceivingMessageForNotify:
+ case EReceivingMessageForListen:
+ {
+ mState = ENotifyingReadMessageSucceeded;
+ MmsServerConnectionFactory::getFactory().setPendingMsgFlag(
+ mUri, true);
+ mListener->msgArrived();
+ break;
+ }
+ case ENotifyingReadMessageSucceeded:
+ {
+ break;
+ }
+ case ENotifyingClose:
+ {
+ mClientEntry->RemoveObserver(*this);
+ if (mMmsApplicationAdapter)
+ {
+ mMmsApplicationAdapter->UnregisterL(*mApplicationId);
+ delete mMmsApplicationAdapter;
+ mMmsApplicationAdapter = NULL;
+ }
+ if (mClientEntry)
+ {
+ delete mClientEntry;
+ mClientEntry = NULL;
+ }
+ if (mSession)
+ {
+ delete mSession;
+ mSession = NULL;
+ }
+ pthread_cond_signal(&mCondVar);
+ CActiveScheduler::Stop();
+ break;
+ }
+ default:
+ {
+ ELOG(EWMA,"MMS : Not a Valid Case");
+ }
+ }
+ if (mState != ENotifyingClose)
+ {
+ iStatus = KRequestPending;
+ SetActive();
+ }
+ pthread_mutex_unlock(&mMutex);
+}
+
+//-----------------------------------------------------------------------------
+// MmsRequestCompleted
+// Start a push midlet register for the mms push
+//-----------------------------------------------------------------------------
+void S60MmsServerConnection::MmsRequestCompleted()
+{
+ if (IsActive())
+ {
+ TRequestStatus *status = &iStatus;
+ mThread.RequestComplete(status, KErrNone);
+ }
+}
+
+}//end of namespace wma
+}//end of namespace java
+