📄 mmstransport.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 + -