⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmstransport.cpp

📁 Symbian OS C++ for Mobile Phones Volume 3 源码
💻 CPP
字号:
// Copyright (c) 2004 - 2007, Symbian Software Ltd. All rights reserved.

#include <utf.h>
#include <eikenv.h>

#include "mmstransport.h"


_LIT(KSmilFileName, "oandx.smil");


// -------- (de)allocation --------

CMmsTransport* CMmsTransport::NewL(TAny* aTransportCreateInfo)
/**
	This factory function is defined so the class can be instantiated
	via ECOM, which means it can only take a single TAny* argument.
	
	@param	aTransportCreateInfo	Pointer to an instance of
							TTransportCreateInfo, which contains the
							data required to allocate the transport.
	@return					Transport that sends messages to a remote
							device over MMS.  This is owned by the caller.
 */
	{
	const TTransportInterfaceCreateInfo& tci =
		*reinterpret_cast<TTransportInterfaceCreateInfo*>(aTransportCreateInfo);
	return New2L(tci.iObserver, *tci.iAddress, tci.iInitListen);
	}

CMmsTransport* CMmsTransport::New2L(MTransportObserver& aObserver, const TDesC& aAddress, TBool aInitListen)
/**
	This helper function for NewL allocates a transport using the parameters
	supplied by the ECOM client.

	@param	aObserver		Observer to notify about transport events.
							This is managed by the CTransport superclass.
	@param	aAddress		Remote device's address.  This should be a
							telephone number.
	@param	aInitListen		If true, this object should start by listening
							for an incoming payload.  Otherwise, it should
							wait for its owner to send a payload to the remote
							device.
	@return					Transport that sends messages to a remote
							device via MMS.  This is owned by the caller.
	@see NewL
 */
	{
	CMmsTransport* self = new(ELeave) CMmsTransport(aObserver);
	CleanupStack::PushL(self);
	self->ConstructL(aAddress, aInitListen);
	CleanupStack::Pop(self);
	return self;
	}

CMmsTransport::CMmsTransport(MTransportObserver& aObserver)
/**
	Initializes base class with supplied observer.

	@param	aObserver		Observer to notify about transport events.
							This is managed by the CTransport superclass.
 */
:	CMessageTransport(aObserver)
	{
	// empty.
	}

void CMmsTransport::ConstructL(const TDesC& aAddress, TBool aInitListen)
/**
	Second-phase constructor initializes the CMessageTransport base class,
	and opens the MMS MTM.

	@param	aAddress		Remote device's address.  This should be a
							telephone number.
	@param	aInitListen		If true, this object should start by listening
							for an incoming payload.  Otherwise, it should
							wait for its owner to send a payload to the remote
							device.
 */
	{
	CMessageTransport::ConstructL(aAddress, aInitListen, /* aObserverSession */ EFalse);
	
	TInt r = iFs.Connect();
	User::LeaveIfError(r);
	
	iClientMtmRegistry = CClientMtmRegistry::NewL(*iMsvSession);
	iMmsClientMtm = static_cast<CMmsClientMtm*>(iClientMtmRegistry->NewMtmL(KUidMsgTypeMultimedia));
	}

CMmsTransport::~CMmsTransport()
/**
	Cancels any outstanding operation and frees resources
	used by this object.
 */
	{
	Cancel();		// ends send operation
	delete iMmsClientMtm;
	delete iClientMtmRegistry;
	iFs.Close();
	}

void CMmsTransport::DestroySendOperation()
/**
	This has no effect if a send operation is not outstanding.
	Otherwise, it cancels the operation and frees the send operation object.
 */
	{
	delete iSendOperation;	// cancels any request
	iSendOperation = 0;
	}


// -------- implement CMessageTransport --------

void CMmsTransport::BuildAndSendMessageL(const TDesC& aPayloadText)
/**
	Implement CMessageTransport by constructing a multimedia message
	with the supplied text as an attachment.

	@param	aPayloadText	Text to send to remote device.
 */
	{
	__MT_ASSERT(iSendOperation == 0, EMtBsAlreadySending);
	
	iMmsClientMtm->SwitchCurrentEntryL(KMsvDraftEntryId);
	
	// create a new message using the MMS service
	TMsvId serviceId = iMmsClientMtm->DefaultServiceL();
	iMmsClientMtm->CreateMessageL(serviceId);

	iMmsClientMtm->AddAddresseeL(*iRemoteAddress);	
	iMmsClientMtm->SetSubjectL(KMmsSubjectLine);
	
	iMmsClientMtm->SaveMessageL();
	
	// add the graphic, payload text, and SMIL document as attachments
	CMsvEntry& mtmEntry = iMmsClientMtm->Entry();
	CMsvStore* s = mtmEntry.EditStoreL();
	CleanupStack::PushL(s);
	
	AddFileAttachmentL(*s, KImageAttachmentName, KImageAttachmentMimeType8);
	AddTextAttachmentL(*s, aPayloadText, KPayloadAttachmentName);
	TMsvAttachmentId smilId = AddFileAttachmentL(*s, KSmilFileName, KMmsApplicationSmil);
	iMmsClientMtm->SetMessageRootL(smilId);	// SMIL document must be root
	
	s->CommitL();
	CleanupStack::PopAndDestroy(s);
	
	// finally, send the message
	TMsvEntry e = mtmEntry.Entry();
	e.SetVisible(ETrue);
	e.SetInPreparation(EFalse);
	mtmEntry.ChangeL(e);
	
	iSendOperation = iMmsClientMtm->SendL(iStatus);
	// SetActive is called by CTransport::SendPayload
	}

void CMmsTransport::AddTextAttachmentL(CMsvStore& aStore, const TDesC& aText, const TDesC& aContentLocation)
/**
	Helper function for BuildAndSendMessageL adds the supplied text as
	an attachment.

	@param	aStore			Store which contains the message's attachments.
	@param	aText			Text to send as an attachment.
	@param	aContentLocation The attachment's Content-Location MIME header.	
							The SMIL document uses this to reference the attachment.
							This should be a file name and extension.
	@see BuildAndSendMessageL
 */
	{
	TInt r;

	HBufC8* text8 = MmsUtils::BuildFramedPayloadLC(aText);
	
	// create a temporary file in the application's private directory
	TFileName fn;
	MmsUtils::FileNameFromPrivateDirL(iFs, fn, aContentLocation);

	// the application is installed on the emulator's Z drive, so switch to C.
#ifdef __WINS__
	TDriveNumber dn;
	TChar ch;
	r = BaflUtils::GetSystemDrive(dn);
	if (r != KErrNone)
		dn = EDriveC;
	
	r = iFs.CreatePrivatePath(dn);

	if (r == KErrAlreadyExists)
		r = KErrNone;

	if (r == KErrNone)
		r = RFs::DriveToChar(dn, ch);

	User::LeaveIfError(r);
	fn[0] = ch;
#endif

	RFile f;
	r = f.Create(iFs, fn, EFileStreamText | EFileWrite | EFileShareAny);
	User::LeaveIfError(r);
	
	r = f.Write(*text8);
	if (r == KErrNone)
		r = f.Flush();
	// MTM may not read from start of file so have to rewind here
	if (r == KErrNone)
		{
		TInt startPos = 0;	// reference arg
		r = f.Seek(ESeekStart, startPos);
		}
	if (r == KErrNone)
		{
		TRAP(r, AddFileAttachmentL(aStore, f, aContentLocation, KMmsTextPlain));
		}
	
	f.Close();
	CleanupStack::PopAndDestroy(text8);
	
	// temporary file is not deleted when it is closed, so delete it here
	TInt r2 = iFs.Delete(fn);
	if (r == KErrNone)
		r = r2;
	User::LeaveIfError(r);
	}

TMsvAttachmentId CMmsTransport::AddFileAttachmentL(CMsvStore& aStore, const TDesC& aNameAndExt, const TDesC8& aMimeType)
/**
	Helper function for BuildAndSendMessageL retrieves the supplied file
	from the process' private directory and adds it as an attachment.

	@param	aStore			Store which contains the message's attachments.
	@param	aNameAndExt		The file's name and extension.  This function looks
							for a file with that name in the current process'
							private directory.  The supplied name and extension
							are used as the attachment's Content-Location.
	@param	aMimeType		The file's MIME type.
	@return					The newly-created attachment's ID.
	@see BuildAndSendMessageL
 */
	{
	TFileName fn;
	MmsUtils::FileNameFromPrivateDirL(iFs, fn, aNameAndExt);
	
	RFile f;
	TInt r = f.Open(iFs, fn, EFileStream | EFileRead);
	User::LeaveIfError(r);
	CleanupClosePushL(f);
	
	TMsvAttachmentId id = AddFileAttachmentL(aStore, f, aNameAndExt, aMimeType);
	
	CleanupStack::PopAndDestroy(&f);
	return id;
	}

TMsvAttachmentId CMmsTransport::AddFileAttachmentL(
	CMsvStore& aStore, RFile& aFile, const TDesC& aContentLocation, const TDesC8& aMimeType)
/**
	Helper function for AddTextAttachmentL and AddFileAttachmentL adds the
	supplied file as an attachment.

	@param	aStore			Store which contains the message's attachments.
	@param	aFile			Opened file to add to as an attachment.
	@param	aContentLocation Value for the file's Content-Location MIME header.
	@param	aMimeType		The file's MIME type.
	@return					The newly-created attachment's ID.
	@see BuildAndSendMessageL
 */
	{
	CMsvMimeHeaders* headers = CMsvMimeHeaders::NewLC();
	headers->SetContentLocationL(aContentLocation);
	
	CMsvAttachment* attach = CMsvAttachment::NewL(CMsvAttachment::EMsvFile);
	CleanupStack::PushL(attach);
	
	// Construct a non-const TDesC8 object for the MIME type.
	// This is necessary because CreateAttachment2L takes a TDesC8& instead of a const TDesC8&.
	TPtrC8 mt8(aMimeType);
	
	TMsvAttachmentId id;	// CreateAttachment2L sets this to the new attachment's ID
	iMmsClientMtm->CreateAttachment2L(aStore, aFile, mt8, *headers, attach, id);
	
	CleanupStack::Pop(attach);			// ownership transfers to MTM
	CleanupStack::PopAndDestroy(headers);
	
	return id;
	}

TBool CMmsTransport::ShouldUseReceivedMtmUid(TUid aMtmUid) const
/**
	Implement CMessageTransport by testing if the supplied MTM
	UID is an MMS UID.

	@param	aMtmUid			The incoming message's MTM UID.
	@return					Whether aMtmUid is an MMS UID.
 */
	{
	return aMtmUid == KUidMsgTypeMultimedia;
	}

HBufC* CMmsTransport::ExtractPlainTextLC(CMsvStore& aStore) const
/**
	Implement CMessageTransport by extracting the payload from
	the supplied message store.

	@param	aStore			Store which contains attachments including
							the MMS payload.
	@return					The extracted payload text.
 */
	{
	return MmsUtils::ExtractPlainTextLC(aStore);
	}


// -------- implement CActive, override CTransport --------

void CMmsTransport::RunL()
/**
	Implement CActive and override CTransport.  This function
	is called when a message is received or when the send operation
	completes.
 */
	{
	// if sending then delete the send operation.  (This has
	// no effect if have received incoming message.)	
	DestroySendOperation();

	CTransport::RunL();
	}

void CMmsTransport::DoCancel()
/**
	Implement CActive and override CMessageTransport by
	cancelling an outstanding read or send.
 */
	{
	// if sending then cancel the send operation...
	if (iSendOperation != 0)
		DestroySendOperation();
	// ...else cancel pending read
	else
		CMessageTransport::DoCancel();
	}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -