package org.thoughtcrime.securesms.transport; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.preference.PreferenceManager; import android.telephony.SmsManager; import android.util.Log; import org.thoughtcrime.securesms.ApplicationPreferencesActivity; import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.crypto.SessionCipher; import org.thoughtcrime.securesms.database.model.SmsMessageRecord; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.service.SendReceiveService; import org.thoughtcrime.securesms.service.SmsDeliveryListener; import org.thoughtcrime.securesms.sms.MultipartSmsMessageHandler; import org.thoughtcrime.securesms.sms.OutgoingTextMessage; import org.thoughtcrime.securesms.sms.SmsTransportDetails; import java.util.ArrayList; public class SmsTransport { private final Context context; private final MasterSecret masterSecret; public SmsTransport(Context context, MasterSecret masterSecret) { this.context = context.getApplicationContext(); this.masterSecret = masterSecret; } public void deliver(SmsMessageRecord message) throws UndeliverableMessageException { if (message.isSecure() || message.isKeyExchange()) { deliverSecureMessage(message); } else { deliverPlaintextMessage(message); } } private void deliverSecureMessage(SmsMessageRecord message) throws UndeliverableMessageException { MultipartSmsMessageHandler multipartMessageHandler = new MultipartSmsMessageHandler(); OutgoingTextMessage transportMessage = OutgoingTextMessage.from(message); if (message.isSecure()) { String encryptedMessage = getAsymmetricEncrypt(masterSecret, message.getBody().getBody(), message.getIndividualRecipient()); transportMessage = transportMessage.withBody(encryptedMessage); } ArrayList messages = multipartMessageHandler.divideMessage(transportMessage); ArrayList sentIntents = constructSentIntents(message.getId(), message.getType(), messages); ArrayList deliveredIntents = constructDeliveredIntents(message.getId(), message.getType(), messages); Log.w("SmsTransport", "Secure divide into message parts: " + messages.size()); for (int i=0;i messages = SmsManager.getDefault().divideMessage(message.getBody().getBody()); ArrayList sentIntents = constructSentIntents(message.getId(), message.getType(), messages); ArrayList deliveredIntents = constructDeliveredIntents(message.getId(), message.getType(), messages); String recipient = message.getIndividualRecipient().getNumber(); // XXX moxie@thoughtcrime.org 1/7/11 -- There's apparently a bug where for some unknown recipients // and messages, this will throw an NPE. I have no idea why, so I'm just catching it and marking // the message as a failure. That way at least it doesn't repeatedly crash every time you start // the app. // d3sre 12/10/13 -- extended the log file to further analyse the problem try { SmsManager.getDefault().sendMultipartTextMessage(recipient, null, messages, sentIntents, deliveredIntents); } catch (NullPointerException npe) { Log.w("SmsTransport", npe); Log.w("SmsTransport", "Recipient: " + recipient); Log.w("SmsTransport", "Message Parts: " + messages.size()); try { for (int i=0;i constructSentIntents(long messageId, long type, ArrayList messages) { ArrayList sentIntents = new ArrayList(messages.size()); for (int i=0;i constructDeliveredIntents(long messageId, long type, ArrayList messages) { if (!PreferenceManager.getDefaultSharedPreferences(context) .getBoolean(ApplicationPreferencesActivity.SMS_DELIVERY_REPORT_PREF, false)) { return null; } ArrayList deliveredIntents = new ArrayList(messages.size()); for (int i=0;i