diff -r 000000000000 -r 59dfe4ae66d0 rcsimengine/src/chatcontactmanagerimpl_sym.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rcsimengine/src/chatcontactmanagerimpl_sym.cpp Fri Oct 08 18:07:26 2010 +0530 @@ -0,0 +1,610 @@ +/* +* Copyright (c) 2009-2010 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: +* RCS IM Library - Initial version +* +*/ + + + +#include +#include +#include +#include +#include +#include +#include +#include "chatsession.h" +#include "chatcontactmanager.h" +#include "chatcontactmanagerimpl_sym.h" +#include "chatsessionimpl_sym.h" +#include "msrpchatsessiondata_sym.h" +#include +#include +#include +#include "qcontactfilter.h" + +using namespace RcsIMLib; + + +ChatContactManagerImpl::ChatContactManagerImpl(ChatContactManager *apCntManager):mParent(apCntManager),mProfile(NULL) +{ + QT_TRAP_THROWING(setupMceManagerL()); + mManager = new QContactManager("symbian"); + + QContact self = mManager->contact(mManager->selfContactId()); + //mMyID = self.localId(); + + // To get Self SIP Uri. + QContactDetail selfContactDetail = self.detail(QContactOnlineAccount::DefinitionName); + const QContactOnlineAccount &onlineUrl = static_cast(selfContactDetail); + QString selfSipUri = onlineUrl.accountUri(); + TPtrC16 dataPtr(reinterpret_cast(selfSipUri.utf16())); + mOriginatorUri = HBufC8::NewL(dataPtr.Length()); + mOriginatorUri->Des().Copy(dataPtr); + +} + + +ChatContactManagerImpl::~ChatContactManagerImpl() + { + + for(int i=0;iState(); + + if (mSessionState <= CMceSession::EEstablished) + mMceSessions[i]->TerminateL(0,0,0); + + } + + mMceSessions.ResetAndDestroy();//deletes streams, sources and sinks + mMceSessions.Close(); + mChatSessionArray.ResetAndDestroy(); + mChatSessionArray.Close(); + delete mManager; + delete mMceMgr; + + //delete mProfile; + mAllprofiles.ResetAndDestroy(); + mAllprofiles.Close(); + + delete mProfileReg; + delete mSip; + delete mOriginatorUri; + + } + +void ChatContactManagerImpl::closeSession(RcsChatId sessID) +{ + + CMceSession *currentSession = reinterpret_cast(sessID); + + int mSessionState = currentSession->State(); + + if (mSessionState == CMceSession::EEstablished) + currentSession->TerminateL(); + + //remove and close + + TInt idx = mMceSessions.Find(currentSession); + if (idx != KErrNotFound) + { + delete currentSession; + mMceSessions.Remove(idx); + } + + for(int i=0;iiMceSession == currentSession) + { + delete mChatSessionArray[i]; + mChatSessionArray.Remove(i); + break; + } + } + } + +void ChatContactManagerImpl::acceptIncomingSession(RcsChatId sessID) +{ + CMceInSession *currentSession = reinterpret_cast(sessID); + if (currentSession->State() == CMceSession::EProceeding) + { + currentSession->AcceptL(); + } + } + + + +RcsIMLib::RcsChatId ChatContactManagerImpl::createChatSession(QContactLocalId contactId, QString initMsg) +{ + RcsIMLib::RcsChatId id = 0; + QT_TRAP_THROWING(id = createChatSessionL(contactId, initMsg)); + //QT_TRYCATCH_ERROR(id = createChatSessionL(contactId, initMsg)); + return id; +} + + +RcsIMLib::RcsChatId ChatContactManagerImpl::createChatSessionL(QContactLocalId contactId, QString initMsg) +{ + // To get recipient SIP Uri. + const QContact buddy = mManager->contact(contactId); + QContactDetail buddyContactDetail = buddy.detail(QContactOnlineAccount::DefinitionName); + const QContactOnlineAccount &onlineUrl = static_cast(buddyContactDetail); + QString buddySipUri = onlineUrl.accountUri(); + TPtrC16 dataPtr(reinterpret_cast(buddySipUri.utf16())); + HBufC8 *recipientUri = HBufC8::NewL(dataPtr.Length()); + CleanupStack::PushL(recipientUri); + recipientUri->Des().Copy(dataPtr); + + CMceOutSession *outSess ; + if(mProfile) + { + outSess = CMceOutSession::NewL(*mMceMgr, *mProfile, *recipientUri); + } + else + { + outSess = CMceOutSession::NewL(*mMceMgr, 1,*mOriginatorUri, *recipientUri); + } + CleanupStack::PopAndDestroy(recipientUri); + CleanupStack::PushL(outSess); + + /* Add the out session to the list of MCESessions */ + mMceSessions.Append(outSess); + CleanupStack::Pop(outSess); + + /* Streams Creation */ + // Create the stream for UpLink and Downlink + CMceMessageStream* msgStrmUp = CMceMessageStream::NewL(); + CleanupStack::PushL(msgStrmUp); + + // Message Source + CMceMessageSource* messageSrc = CMceMessageSource::NewL(*mMceMgr); + CleanupStack::PushL(messageSrc); + + //MSRP Sink + CMceMsrpSink* msrpSink = CMceMsrpSink::NewL(); + CleanupStack::Pop(messageSrc); + CleanupStack::PushL(msrpSink); + CleanupStack::PushL(messageSrc); + msgStrmUp->SetSourceL(messageSrc); + CleanupStack::Pop(messageSrc); + + // Add sink to the stream + msgStrmUp->AddSinkL(msrpSink); + CleanupStack::Pop(msrpSink); + msgStrmUp->ConnectionSetUpL(CMceMessageStream::EActive); + + // Set AcceptTypes + CDesC8ArrayFlat *acceptTypes = new(ELeave)CDesC8ArrayFlat(KGranularity); + _LIT8(KtextPlain,"text/plain"); + acceptTypes->AppendL(KtextPlain); + + msrpSink->SetAcceptTypesL(*acceptTypes); + delete acceptTypes; + + _LIT8(KAcceptWrap, "acceptwrap"); + TBuf8 accept(KAcceptWrap); + msrpSink->SetAcceptWrappedTypesL(accept); + + + //outSess->AddStreamL(msgStrmUp); + CleanupStack::Pop(msgStrmUp); + + + // Create the stream for Downlink + CMceMessageStream *msgStrmDown = CMceMessageStream::NewL(); + + // MSRP Source + CMceMsrpSource *msrpSrc = CMceMsrpSource::NewL(); + + // Message Sink + CMceMessageSink* messageSink = CMceMessageSink::NewL(*mMceMgr); + CleanupStack::PushL(msrpSrc); + msgStrmDown->SetSourceL(msrpSrc); + CleanupStack::Pop(msrpSrc); + + // Add sink to the stream + CleanupStack::PushL(messageSink); + msgStrmDown->AddSinkL(messageSink); + CleanupStack::Pop(messageSink); + msgStrmDown->ConnectionSetUpL(CMceMessageStream::EActive); + + CleanupStack::PushL(msgStrmUp); + msgStrmDown->BindL(msgStrmUp); + CleanupStack::Pop(msgStrmUp); + + CleanupStack::PushL(msgStrmDown); + outSess->AddStreamL(msgStrmDown); + CleanupStack::Pop(msgStrmDown); + + /* A new Chat Session with the Platform specific Init Params */ + ChatSession *chatSession = new ChatSession(); + + /* Create the ChatSession here */ + TMsrpChatSession *msrpChatSession = new TMsrpChatSession(); + msrpChatSession->iMceManager = mMceMgr; + msrpChatSession->iMceSession = outSess; + msrpChatSession->iChatSession = chatSession; + msrpChatSession->iStream1 = msgStrmUp; + msrpChatSession->iStream2 = msgStrmDown; + + //chatSession->setPlatformParams(msrpChatSession); + + mChatSessionArray.Append(msrpChatSession); + + + //Start the session establishment here. Emit the signal when everything is + //done. The session will be matched my the ID returned. + //RcsChatId sessID = (RcsChatId)&outSess; + + + //Create the CDesC8Array with the syntax of the subject header and pass it + //such that the INVITE is constructed with Subject header. + + CDesC8ArrayFlat *mSIPHeaders = new CDesC8ArrayFlat(20); + QString mSubjectHeader = "Subject:"+ initMsg; + TPtrC16 mDataPtr(reinterpret_cast(mSubjectHeader.utf16())); + RBuf8 mChatData; + mChatData.Create(300); + mChatData.Copy(mDataPtr); + + mSIPHeaders->AppendL(mChatData); + outSess->EstablishL(0,mSIPHeaders,0,0,0); + + return reinterpret_cast(outSess); +} + +void ChatContactManagerImpl::setupMceManagerL() +{ + //RFileLogger::Write( KLogDir1, KLogFile1, EFileLoggingModeAppend, _L("setupMceManagerL ChkPt 0") ); + //Setup MCE For accepting and receiving chat messages + mMceMgr = CMceManager::NewL(TUid::Uid(0x10009388), &mDataContainer); + + // Set session observer to get the session related state changes + mMceMgr->SetSessionObserver(this); + + // Set InSession Observer to recieve the incoming session + mMceMgr->SetInSessionObserver(this); + mMceMgr->SetDataSinkObserver(this); + + TUid appUid; + + appUid.iUid = 0xA00001EC; //TODO get APPUID Correct + TRAPD(errsip, mSip = CSIP::NewL(appUid , *this)) + //TRAPD(errsip, mSip = CSIP::NewL(TUid::Null(), *this)) + if (!errsip) { + //CleanupStack::PushL(sipClient); + mProfileReg = CSIPProfileRegistry::NewL(*mSip, *this); + //CleanupStack::Pop(mSip); + } + + //assumes first profile is registered and valid + //CleanupStack::PushL(profileReg); + //mProfile = profileReg->DefaultProfileL(); + + + //later check for tag matches + + + mProfileReg->ProfilesL(mAllprofiles); + if (mAllprofiles.Count()) + { + mProfile = mAllprofiles[0]; + } + + //CleanupStack::PopAndDestroy(profileReg); + //CleanupStack::PopAndDestroy(sipClient); +} + + +void ChatContactManagerImpl::SessionStateChanged( CMceSession& aSession, TMceTransactionDataContainer* aContainer) +{ + if (aSession.State() == CMceSession::EEstablished) + { + + CMceMessageStream* downlinkStr = NULL; + CMceMessageStream* uplinkStr = NULL; + + GetStreams(aSession, uplinkStr, downlinkStr ); + + if (uplinkStr && uplinkStr->Source() && + uplinkStr->Source()->Type() == KMceMessageSource) + { + uplinkStr->Source()->DisableL(); + if (!uplinkStr->Source()->IsEnabled()) + uplinkStr->Source()->EnableL(); + } + + if (downlinkStr && downlinkStr->Sinks().Count() > 0) + { + // assume only one sink is added + downlinkStr->Sinks()[0]->DisableL(); + if (! downlinkStr->Sinks()[0]->IsEnabled() ) + downlinkStr->Sinks()[0]->EnableL(); + } + + for(int i=0;iiMceSession == &aSession) + { + mChatSessionArray[i]->iStream1 = uplinkStr; + mChatSessionArray[i]->iStream2 = downlinkStr; + mChatSessionArray[i]->iChatSession->setPlatformParams(mChatSessionArray[i]); + break; + } + } + + +/* //can be terminated without establishment + // A new Chat Session with the Platform specific Init Params + ChatSession *chatSession = new ChatSession(); + + //Create the ChatSession here + TMsrpChatSession *msrpChatSession = new TMsrpChatSession(); + msrpChatSession->iMceManager = mMceMgr; + msrpChatSession->iMceSession = &aSession; + msrpChatSession->iChatSession = chatSession; + msrpChatSession->iStream1 = uplinkStr; + msrpChatSession->iStream2 = downlinkStr; + + chatSession->setPlatformParams(msrpChatSession); + + mChatSessionArray.Append(msrpChatSession); +*/ + + /* Notify the UI that Session is established. Pointer to aSession + * serves as the key */ + for(int i=0;iiMceSession == &aSession) + { + emit mParent->sessionEstablised(reinterpret_cast(&aSession), mChatSessionArray[i]->iChatSession); + break; + } + } + + + } + else if (aSession.State() == CMceSession::EProceeding) + { + //get originator + const TDesC8& remoteURI = aSession.Originator(); + const QString remoteSIPURI = QString::fromUtf8((const char*)remoteURI.Ptr(),remoteURI.Length()); + + //Pass the remote sip uri as a filter and fetch the buddy name. + //Also emit a signal here for incomingChatSession with the contactID + + // To fetch the buddy name using the sip URI. + QList order; + QStringList list; + QContactDetailFilter filter; + filter.setDetailDefinitionName(QContactOnlineAccount::DefinitionName, QContactOnlineAccount::SubTypeSip); + filter.setValue(remoteSIPURI); + + QList allContacts; + allContacts = mManager->contacts(filter); + unsigned int buddyID = 0; + if(allContacts.count()) + { + buddyID = allContacts[0].localId(); + } + + QString imMsg; + + + for(int i=0;iiMceSession == &aSession) + { + imMsg = mChatSessionArray[i]->iInitMsg; + break; + } + } + + + //emit on SSC to proceeding as a result of call to updateL //see insession header + //emit after update or could lead to accept call before update, little chance as user interaction involved + emit mParent->incomingChatSession(buddyID, remoteSIPURI, imMsg, reinterpret_cast(&aSession)); + } + else if (aSession.State() == CMceSession::ETerminated) + { + for(int i=0;iiMceSession == &aSession) + { + emit mParent->sessionTerminated(reinterpret_cast(&aSession), mChatSessionArray[i]->iChatSession); + break; + } + } + + } +} + + + +void ChatContactManagerImpl::SessionConnectionStateChanged( CMceSession& , TBool /*aActive*/ ) +{ +} + +void ChatContactManagerImpl::Failed( CMceSession& /*aSession*/, TInt /*aError*/ ) +{ +} + +void ChatContactManagerImpl::UpdateFailed(CMceSession& /*aSession*/, TMceTransactionDataContainer* /*aContainer*/ ) +{ +} + +// From MSIPProfileAgentObserver +void ChatContactManagerImpl::ProfileRegistryEventOccurred(TUint32 /*aProfileId*/, TEvent /*aEvent*/) +{ +} + +void ChatContactManagerImpl::ProfileRegistryErrorOccurred(TUint32 /*aProfileId*/, TInt /*aError*/) +{ +} + +// From MSIPObserver +void ChatContactManagerImpl::IncomingRequest(TUint32 /*aIapId*/, CSIPServerTransaction* /*aTransaction*/) +{ +} + +void ChatContactManagerImpl::TimedOut(CSIPServerTransaction& /*aTransaction*/) +{ +} + +// From MMceInSessionObserver +void ChatContactManagerImpl::IncomingSession(CMceInSession* aSession, TMceTransactionDataContainer* aContainer ) +{ + if (aSession->State() == CMceSession::EIncoming) + { + /////////////////////// + QString imMsg; + //Fetch the message from the SIP INVITE + CDesC8Array *mSIPHeader = aContainer->GetHeaders(); + TInt count = mSIPHeader->MdcaCount(); + + for (int i=0; iMdcaPoint(i); + QString header = QString::fromUtf8((const char*)data.Ptr(),data.Length()); + if (header.contains("Subject",Qt::CaseSensitive)) + { + QChar sep = ':'; + //QString mChatData = header.section(sep,1); + imMsg = header.section(sep,1); + } + else + { + //QString mChatData = ""; + imMsg = ""; + } + } + ////////////////////// + + // get the stream for this incoming session to set the MSRP capabilities + CMceMessageStream* downlinkStr = NULL; + CMceMessageStream* uplinkStr = NULL; + GetStreams(*aSession, uplinkStr, downlinkStr); + + ChatSession *chatSession = new ChatSession(); + + // Create the ChatSession here + TMsrpChatSession *msrpChatSession = new TMsrpChatSession(); + msrpChatSession->iMceManager = mMceMgr; + msrpChatSession->iMceSession = aSession; + msrpChatSession->iChatSession = chatSession; + msrpChatSession->iStream1 = uplinkStr; + msrpChatSession->iStream2 = downlinkStr; + msrpChatSession->iInitMsg = imMsg; + + mChatSessionArray.Append(msrpChatSession); + + + if (downlinkStr ) + { + CMceMsrpSource* msrpSource = static_cast (downlinkStr->Source()); + if(msrpSource) + { + downlinkStr->ConnectionSetUpL(CMceMessageStream::EPassive); + //uplinkStr->ConnectionSetUpL(CMceMessageStream::EPassive); + + // Set AcceptTypes + CDesC8ArrayFlat *acceptTypes = new(ELeave)CDesC8ArrayFlat(KGranularity); + _LIT8(KtextPlain,"text/plain"); + _LIT8(KMessageCpim, "message/cpim"); + acceptTypes->AppendL(KtextPlain); + acceptTypes->AppendL(KMessageCpim); + + msrpSource->SetAcceptTypesL(*acceptTypes); + delete acceptTypes; + + _LIT8(KAcceptWrap, "acceptwrap"); + TBuf8 accept(KAcceptWrap); + msrpSource->SetAcceptWrappedTypesL(accept); + } + } + + /* Add the out session to the list of MCESessions */ + mMceSessions.Append(aSession); + aSession->UpdateL(); + } +} + + +void ChatContactManagerImpl::IncomingUpdate(CMceSession& , CMceInSession* , TMceTransactionDataContainer* ) +{ +} + +void ChatContactManagerImpl::DataReceived(CMceMediaStream& aStream, CMceMediaSink& /*aSink*/, const TDesC8& aData) +{ + /* Find the Session for which this Message is intented */ + for(int i=0; iiStream1 == &aStream || mChatSessionArray[i]->iStream2 == &aStream) + { + ChatSessionImpl *pImpl = static_cast(mChatSessionArray[i]->iChatSession->getPlatformImpl()); + pImpl->incomingData(aData); + } + } +} + + +void ChatContactManagerImpl::GetStreams(CMceSession& aSession, CMceMessageStream*& aUplinkStr, CMceMessageStream*& aDownlinkStr ) + { + RPointerArray streams = aSession.Streams(); + for (TInt i=0; iType() == KMceMessage && + streams[i]->Source() && + streams[i]->Source()->Type() == KMceMSRPSource) + { + aDownlinkStr =static_cast (streams[i]); + //break; + } + + if (streams[i]->Type() == KMceMessage && + streams[i]->Source() && + streams[i]->Source()->Type() == KMceMessageSource) + { + aUplinkStr =static_cast (streams[i]); + //break; + } + if (aDownlinkStr == NULL && streams[i]->BoundStream()) + { + if (streams[i]->BoundStreamL().Type() == KMceMessage && + streams[i]->BoundStreamL().Source() && + streams[i]->BoundStreamL().Source()->Type() == KMceMSRPSource) + { + CMceMessageStream& stream =static_cast (streams[i]->BoundStreamL()); + aDownlinkStr = &stream; + // break; + } + } + + if (aUplinkStr == NULL && streams[i]->BoundStream()) + { + if (streams[i]->BoundStreamL().Type() == KMceMessage && + streams[i]->BoundStreamL().Source() && + streams[i]->BoundStreamL().Source()->Type() == KMceMessageSource) + { + CMceMessageStream& stream =static_cast (streams[i]->BoundStreamL()); + aUplinkStr = &stream; + } + } + } // for loop + + } + + +