void CSMSSender::CreateSMSMessageL(const TDesC& aText, const TDesC& aAddress) /** Prepare SMS specific objects ready to send via ESOCK @param aText buffer containing ascii contents of message to send @param aAddress buffer with telephone number of SMS receiver */ { #ifndef __WINS__ TSmsAddr smsAddr; smsAddr.SetSmsAddrFamily(ESmsAddrSendOnly); smsAddr.SetPort(smsAddr.Port() + 1);//ycf __LOGSTR_TOFILE("sockent bind"); iSocket.Bind(smsAddr); CSmsBuffer* smsBuffer = CSmsBuffer::NewL(); //CleanupStack::PushL(smsBuffer) is NOT used because CSmsMessage takes ownership of our buffer :-) CSmsMessage* smsMsg = CSmsMessage::NewL(iFs, CSmsPDU::ESmsSubmit, smsBuffer); CleanupStack::PushL(smsMsg); TSmsUserDataSettings smsSettings; smsSettings.SetAlphabet(TSmsDataCodingScheme::ESmsAlphabetUCS2); smsSettings.SetTextCompressed(EFalse); smsMsg->SetUserDataSettingsL(smsSettings); TBuf<KMaxAddressSize> toAddress; toAddress.Copy(aAddress); smsMsg->SetToFromAddressL(toAddress); //Get service centre address. // The method used here assumes the SMS settings are provisioned, which is true in known cases. // There are alternative partner-only APIs, however this allow this source to be kept public #ifdef EKA2 CSmsSettings* smsSCSettings = CSmsSettings::NewL(); CleanupStack::PushL(smsSCSettings); CSmsAccount* smsAccount=CSmsAccount::NewLC(); smsAccount->LoadSettingsL(*smsSCSettings); // index of the default service centre address for this service TInt defIndex; User::LeaveIfError(defIndex = smsSCSettings->DefaultServiceCenter()); // Get the service center address CSmsServiceCenter& scAddr = smsSCSettings->GetServiceCenter(defIndex); TPtrC theAddress=scAddr.Address(); HBufC* serviceCentreAddress=HBufC::NewLC(theAddress.Length()); *serviceCentreAddress=theAddress; smsMsg->SmsPDU().SetServiceCenterAddressL(*serviceCentreAddress); CleanupStack::PopAndDestroy(serviceCentreAddress);// CleanupStack::PopAndDestroy(smsAccount); CleanupStack::PopAndDestroy(smsSCSettings); #else TMsvId serviceId; CObserver* pObserver = new (ELeave) CObserver(); CleanupStack::PushL(pObserver); CMsvSession* pSession = CMsvSession::OpenSyncL(*pObserver); CleanupStack::PushL(pSession); TSmsUtilities::ServiceIdL(*pSession, serviceId, KUidMsgTypeSMS); CMsvEntry* service = pSession->GetEntryL(serviceId); CleanupStack::PushL(service); CMsvStore* msvstore = service->ReadStoreL(); CleanupStack::PushL(msvstore); CSmsSettings* smsSCSettings = CSmsSettings::NewL(); CleanupStack::PushL(smsSCSettings); smsSCSettings->RestoreL(*msvstore); TInt defIndex; User::LeaveIfError(defIndex = smsSCSettings->DefaultSC()); defIndex = smsSCSettings->DefaultSC(); // Get the default service center address CSmsNumber& scAddr = smsSCSettings->SCAddress(defIndex); TPtrC theAddress=scAddr.Address(); HBufC* serviceCentreAddress=HBufC::NewLC(theAddress.Length()); *serviceCentreAddress=theAddress; smsMsg->SmsPDU().SetServiceCenterAddressL(*serviceCentreAddress); CleanupStack::PopAndDestroy(serviceCentreAddress);// CleanupStack::PopAndDestroy(smsSCSettings); //smsSettings CleanupStack::PopAndDestroy(msvstore); CleanupStack::PopAndDestroy(service); CleanupStack::PopAndDestroy(pSession); CleanupStack::PopAndDestroy(pObserver); #endif //convert to wide HBufC* payload = HBufC::NewL(aText.Length()); CleanupStack::PushL(payload); TPtr pPayload=payload->Des(); pPayload.Copy(aText); //copy from narrow to wide and convert smsBuffer->InsertL(0, pPayload); //copies payload RSmsSocketWriteStream writeStream(iSocket); CleanupClosePushL(writeStream); writeStream << *smsMsg; // remember << operator _CAN_ leave __LOGSTR_TOFILE("write stream commit"); writeStream.CommitL(); CleanupStack::PopAndDestroy(&writeStream); CleanupStack::PopAndDestroy(2);//smsMsg, payload #endif }
void CSmsFile::send_messageL(const TDesC& recipient, const TDesC& body) { if (iStatus==KRequestPending) { User::Leave(KErrServerBusy); } state=_L("send_messageL"); TMsvEntry newEntry; // This represents an entry in the Message Server index newEntry.iMtm = KUidMsgTypeSMS; // message type is CSmsFile newEntry.iType = KUidMsvMessageEntry; // this defines the type of the entry: message newEntry.iServiceId = KMsvLocalServiceIndexEntryId; // ID of local service (containing the standard folders) newEntry.iDate.HomeTime(); // set the date of the entry to home time newEntry.SetInPreparation(ETrue); // a flag that this message is in preparation // get ref to outbox state=_L("NewL"); CMsvEntry *entry =CMsvEntry::NewL(*iSession, KMsvGlobalOutBoxIndexEntryId ,TMsvSelectionOrdering()); CleanupStack::PushL(entry); // create message in outbox state=_L("CreateL"); entry->CreateL(newEntry); state=_L("GetEntry"); entry = iSession->GetEntryL(newEntry.Id()); // SetCurrentEntryL takes ownership of the CMsvEntry state=_L("SetCurrentEntry"); iMtm->SetCurrentEntryL(entry); CleanupStack::Pop(); // entry state=_L("Entry()"); TMsvEntry msvEntry = (iMtm->Entry()).Entry(); state=_L("Body()"); CRichText& mtmBody = iMtm->Body(); mtmBody.Reset(); state=_L("set message"); mtmBody.InsertL(0, body); // insert our msg tag as the body text // set iRecipient into the Details of the entry msvEntry.iDetails.Set(recipient); // set recipient info in details msvEntry.SetInPreparation(EFalse); // set inPreparation to false msvEntry.SetSendingState(KMsvSendStateWaiting); // set the sending state (immediately) msvEntry.iDate.HomeTime(); // set time to Home Time // To handle the CSmsFile specifics we start using SmsMtm CSmsClientMtm* smsMtm = STATIC_CAST(CSmsClientMtm*, iMtm); state=_L("RestoreServiceAndSettingsL"); smsMtm->RestoreServiceAndSettingsL(); state=_L("set header"); // CSmsHeader encapsulates data specific for CSmsFile messages, // like service center number and options for sending. CSmsHeader& header = smsMtm->SmsHeader(); state=_L("get options"); if (!sendOptions) { sendOptions = CSmsSettings::NewL(); sendOptions->CopyL(smsMtm->ServiceSettings()); // restore existing settings state=_L("SetDelivery"); sendOptions->SetDelivery(ESmsDeliveryImmediately); // set to be delivered immediately } // set send options // ERROR HERE! state=_L("SetSmsSettingsL"); header.SetSmsSettingsL(*sendOptions); state=_L("check sc"); // let's check if there's sc address if (header.Message().ServiceCenterAddress().Length() == 0) { // no, there isn't. We assume there is at least one sc number set and use // the default SC number. CSmsSettings* serviceSettings = &(smsMtm->ServiceSettings()); // if number of scaddresses in the list is null if (!serviceSettings->NumSCAddresses()) { // FIXME: what to do? User::Leave(1); } else { // set sc address to default. CSmsNumber* sc = 0; sc = &(serviceSettings->SCAddress(serviceSettings->DefaultSC())); header.Message().SetServiceCenterAddressL(sc->Address()); } } state=_L("add addresses"); // Add our recipient to the list, takes in two TDesCs, first is real address and second is an alias // works also without the alias parameter. smsMtm->AddAddresseeL(recipient, msvEntry.iDetails); // if message is to be deleted after sending, mark with our UID msvEntry.iMtmData3 = KUidRippleVaultApp.iUid; state=_L("save"); // save message iMtm->Entry().ChangeL(msvEntry); // make sure that we are handling the right entry smsMtm->SaveMessageL(); // closes the message state=_L("move"); // This moves the message entry to outbox, we'll schedule it for sending after this. // TMsvId movedId = MoveMessageEntryL( KMsvGlobalOutBoxIndexEntryId ); // move message to outbox TMsvId movedId = iMtm->Entry().Entry().Id(); // We must create an entry selection for message copies (although now we only have one message in selection) CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection; CleanupStack::PushL(selection); selection->AppendL(movedId); // add our message to the selection TBuf8<1> dummyParams; // CCommandAbsorbingControl::NewLC(); state=_L("InvokeAsyncFunctionL"); // invoking async schedule copy command on our mtm op=iMtm->InvokeAsyncFunctionL( ESmsMtmCommandScheduleCopy, *selection, dummyParams, iStatus); CleanupStack::Pop(); // selection #ifdef __LOGME__ iAppUi.LogText.Copy(_L("SENT\n")); iAppUi.WriteLogFile(iAppUi.LogText); #endif SetActive(); //return KErrNone; }