use of com.google.android.mms.pdu_alt.RetrieveConf in project Signal-Android by signalapp.
the class IncomingLegacyMmsConnection method retrieve.
public RetrieveConf retrieve(Apn contentApn, byte[] transactionId, boolean usingMmsRadio, boolean useProxyIfAvailable) throws IOException, ApnUnavailableException {
byte[] pdu = null;
final boolean useProxy = useProxyIfAvailable && contentApn.hasProxy();
final String targetHost = useProxy ? contentApn.getProxy() : Uri.parse(contentApn.getMmsc()).getHost();
if (checkRouteToHost(context, targetHost, usingMmsRadio)) {
Log.w(TAG, "got successful route to host " + targetHost);
pdu = execute(constructRequest(contentApn, useProxy));
}
if (pdu == null) {
throw new IOException("Connection manager could not obtain route to host.");
}
RetrieveConf retrieved = (RetrieveConf) new PduParser(pdu).parse();
if (retrieved == null) {
Log.w(TAG, "Couldn't parse PDU, byte response: " + Arrays.toString(pdu));
Log.w(TAG, "Couldn't parse PDU, ASCII: " + new String(pdu));
throw new IOException("Bad retrieved PDU");
}
sendRetrievedAcknowledgement(transactionId, usingMmsRadio, useProxy);
return retrieved;
}
use of com.google.android.mms.pdu_alt.RetrieveConf in project Signal-Android by signalapp.
the class IncomingLollipopMmsConnection method retrieve.
@Override
@TargetApi(VERSION_CODES.LOLLIPOP)
@Nullable
public synchronized RetrieveConf retrieve(@NonNull String contentLocation, byte[] transactionId, int subscriptionId) throws MmsException {
beginTransaction();
try {
MmsBodyProvider.Pointer pointer = MmsBodyProvider.makeTemporaryPointer(getContext());
Log.w(TAG, "downloading multimedia from " + contentLocation + " to " + pointer.getUri());
SmsManager smsManager;
if (VERSION.SDK_INT >= 22 && subscriptionId != -1) {
smsManager = SmsManager.getSmsManagerForSubscriptionId(subscriptionId);
} else {
smsManager = SmsManager.getDefault();
}
smsManager.downloadMultimediaMessage(getContext(), contentLocation, pointer.getUri(), null, getPendingIntent());
waitForResult();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Util.copy(pointer.getInputStream(), baos);
pointer.close();
// + Hex.dump(baos.toByteArray()));
Log.w(TAG, baos.size() + "-byte response: ");
RetrieveConf retrieved = (RetrieveConf) new PduParser(baos.toByteArray()).parse();
if (retrieved == null)
return null;
sendRetrievedAcknowledgement(transactionId, retrieved.getMmsVersion(), subscriptionId);
return retrieved;
} catch (IOException | TimeoutException e) {
Log.w(TAG, e);
throw new MmsException(e);
} finally {
endTransaction();
}
}
use of com.google.android.mms.pdu_alt.RetrieveConf in project Signal-Android by signalapp.
the class MmsDownloadJob method onRun.
@Override
public void onRun(MasterSecret masterSecret) {
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
Optional<MmsDatabase.MmsNotificationInfo> notification = database.getNotification(messageId);
if (!notification.isPresent()) {
Log.w(TAG, "No notification for ID: " + messageId);
return;
}
try {
if (notification.get().getContentLocation() == null) {
throw new MmsException("Notification content location was null.");
}
if (!TextSecurePreferences.isPushRegistered(context)) {
throw new MmsException("Not registered");
}
database.markDownloadState(messageId, MmsDatabase.Status.DOWNLOAD_CONNECTING);
String contentLocation = notification.get().getContentLocation();
byte[] transactionId = new byte[0];
try {
if (notification.get().getTransactionId() != null) {
transactionId = notification.get().getTransactionId().getBytes(CharacterSets.MIMENAME_ISO_8859_1);
} else {
Log.w(TAG, "No transaction ID!");
}
} catch (UnsupportedEncodingException e) {
Log.w(TAG, e);
}
Log.w(TAG, "Downloading mms at " + Uri.parse(contentLocation).getHost() + ", subscription ID: " + notification.get().getSubscriptionId());
RetrieveConf retrieveConf = new CompatMmsConnection(context).retrieve(contentLocation, transactionId, notification.get().getSubscriptionId());
if (retrieveConf == null) {
throw new MmsException("RetrieveConf was null");
}
storeRetrievedMms(contentLocation, messageId, threadId, retrieveConf, notification.get().getSubscriptionId(), notification.get().getFrom());
} catch (ApnUnavailableException e) {
Log.w(TAG, e);
handleDownloadError(messageId, threadId, MmsDatabase.Status.DOWNLOAD_APN_UNAVAILABLE, automatic);
} catch (MmsException e) {
Log.w(TAG, e);
handleDownloadError(messageId, threadId, MmsDatabase.Status.DOWNLOAD_HARD_FAILURE, automatic);
} catch (MmsRadioException | IOException e) {
Log.w(TAG, e);
handleDownloadError(messageId, threadId, MmsDatabase.Status.DOWNLOAD_SOFT_FAILURE, automatic);
} catch (DuplicateMessageException e) {
Log.w(TAG, e);
database.markAsDecryptDuplicate(messageId, threadId);
} catch (LegacyMessageException e) {
Log.w(TAG, e);
database.markAsLegacyVersion(messageId, threadId);
} catch (NoSessionException e) {
Log.w(TAG, e);
database.markAsNoSession(messageId, threadId);
} catch (InvalidMessageException e) {
Log.w(TAG, e);
database.markAsDecryptFailed(messageId, threadId);
}
}
use of com.google.android.mms.pdu_alt.RetrieveConf in project Signal-Android by WhisperSystems.
the class IncomingLollipopMmsConnection method retrieve.
@Override
@TargetApi(VERSION_CODES.LOLLIPOP)
@Nullable
public synchronized RetrieveConf retrieve(@NonNull String contentLocation, byte[] transactionId, int subscriptionId) throws MmsException {
beginTransaction();
try {
MmsBodyProvider.Pointer pointer = MmsBodyProvider.makeTemporaryPointer(getContext());
final String transactionIdString = Util.toIsoString(transactionId);
Log.i(TAG, String.format(Locale.ENGLISH, "Downloading subscriptionId=%s multimedia from '%s' [transactionId='%s'] to '%s'", subscriptionId, contentLocation, transactionIdString, pointer.getUri()));
SmsManager smsManager;
if (VERSION.SDK_INT >= 22 && subscriptionId != -1) {
smsManager = SmsManager.getSmsManagerForSubscriptionId(subscriptionId);
} else {
smsManager = SmsManager.getDefault();
}
final Bundle configOverrides = smsManager.getCarrierConfigValues();
if (configOverrides.getBoolean(SmsManager.MMS_CONFIG_APPEND_TRANSACTION_ID)) {
if (!contentLocation.contains(transactionIdString)) {
Log.i(TAG, "Appending transactionId to contentLocation at the direction of CarrierConfigValues. New location: " + contentLocation);
contentLocation += transactionIdString;
} else {
Log.i(TAG, "Skipping 'append transaction id' as contentLocation already contains it");
}
}
if (TextUtils.isEmpty(configOverrides.getString(SmsManager.MMS_CONFIG_USER_AGENT))) {
configOverrides.remove(SmsManager.MMS_CONFIG_USER_AGENT);
}
if (TextUtils.isEmpty(configOverrides.getString(SmsManager.MMS_CONFIG_UA_PROF_URL))) {
configOverrides.remove(SmsManager.MMS_CONFIG_UA_PROF_URL);
}
smsManager.downloadMultimediaMessage(getContext(), contentLocation, pointer.getUri(), configOverrides, getPendingIntent());
waitForResult();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
StreamUtil.copy(pointer.getInputStream(), baos);
pointer.close();
// + Hex.dump(baos.toByteArray()));
Log.i(TAG, baos.size() + "-byte response: ");
Bundle configValues = smsManager.getCarrierConfigValues();
boolean parseContentDisposition = configValues.getBoolean(SmsManager.MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION);
RetrieveConf retrieved;
try {
retrieved = (RetrieveConf) new PduParser(baos.toByteArray(), parseContentDisposition).parse();
} catch (NullPointerException e) {
Log.w(TAG, "Badly formatted MMS message caused the parser to fail.", e);
throw new MmsException(e);
}
if (retrieved == null)
return null;
sendRetrievedAcknowledgement(transactionId, retrieved.getMmsVersion(), subscriptionId);
return retrieved;
} catch (IOException | TimeoutException e) {
Log.w(TAG, e);
throw new MmsException(e);
} finally {
endTransaction();
}
}
use of com.google.android.mms.pdu_alt.RetrieveConf in project qksms by moezbhatti.
the class RetrieveTransaction method run.
public void run() {
// } else {
try {
// Change the downloading state of the M-Notification.ind.
DownloadManager.init(mContext.getApplicationContext());
DownloadManager.getInstance().markState(mUri, DownloadManager.STATE_DOWNLOADING);
// Send GET request to MMSC and retrieve the response data.
byte[] resp = getPdu(mContentLocation);
// Parse M-Retrieve.conf
RetrieveConf retrieveConf = (RetrieveConf) new PduParser(resp).parse();
if (null == retrieveConf) {
throw new MmsException("Invalid M-Retrieve.conf PDU.");
}
Uri msgUri = null;
if (isDuplicateMessage(mContext, retrieveConf)) {
// Mark this transaction as failed to prevent duplicate
// notification to user.
mTransactionState.setState(TransactionState.FAILED);
mTransactionState.setContentUri(mUri);
} else {
// Store M-Retrieve.conf into Inbox
PduPersister persister = PduPersister.getPduPersister(mContext);
msgUri = persister.persist(retrieveConf, Inbox.CONTENT_URI, PduPersister.DUMMY_THREAD_ID, true, true, null);
// Use local time instead of PDU time
ContentValues values = new ContentValues(3);
values.put(Mms.DATE, System.currentTimeMillis() / 1000L);
try {
values.put(Mms.DATE_SENT, retrieveConf.getDate());
} catch (Exception ignored) {
}
values.put(Mms.MESSAGE_SIZE, resp.length);
SqliteWrapper.update(mContext, mContext.getContentResolver(), msgUri, values, null, null);
// The M-Retrieve.conf has been successfully downloaded.
mTransactionState.setState(TransactionState.SUCCESS);
mTransactionState.setContentUri(msgUri);
// Remember the location the message was downloaded from.
// Since it's not critical, it won't fail the transaction.
// Copy over the locked flag from the M-Notification.ind in case
// the user locked the message before activating the download.
updateContentLocation(mContext, msgUri, mContentLocation, mLocked);
}
// Delete the corresponding M-Notification.ind.
SqliteWrapper.delete(mContext, mContext.getContentResolver(), mUri, null, null);
// Send ACK to the Proxy-Relay to indicate we have fetched the
// MM successfully.
// Don't mark the transaction as failed if we failed to send it.
sendAcknowledgeInd(retrieveConf);
} catch (Throwable t) {
Timber.e(t, "error");
if ("HTTP error: Not Found".equals(t.getMessage())) {
// Delete the expired M-Notification.ind.
SqliteWrapper.delete(mContext, mContext.getContentResolver(), mUri, null, null);
}
} finally {
if (mTransactionState.getState() != TransactionState.SUCCESS) {
mTransactionState.setState(TransactionState.FAILED);
mTransactionState.setContentUri(mUri);
Timber.e("Retrieval failed.");
}
notifyObservers();
}
// }
}
Aggregations