1 /* 2 * Copyright (C) 2007-2008 Esmertec AG. 3 * Copyright (C) 2007-2008 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package com.android.mms.transaction; 19 20 import com.android.mms.util.SendingProgressTokenManager; 21 22 import android.content.Context; 23 import android.net.Uri; 24 import android.net.NetworkUtils; 25 import android.net.ConnectivityManager; 26 import android.util.Log; 27 28 import java.io.IOException; 29 30 /** 31 * Transaction is an abstract class for notification transaction, send transaction 32 * and other transactions described in MMS spec. 33 * It provides the interfaces of them and some common methods for them. 34 */ 35 public abstract class Transaction extends Observable { 36 private final int mServiceId; 37 38 protected Context mContext; 39 protected String mId; 40 protected TransactionState mTransactionState; 41 protected TransactionSettings mTransactionSettings; 42 43 /** 44 * Identifies push requests. 45 */ 46 public static final int NOTIFICATION_TRANSACTION = 0; 47 /** 48 * Identifies deferred retrieve requests. 49 */ 50 public static final int RETRIEVE_TRANSACTION = 1; 51 /** 52 * Identifies send multimedia message requests. 53 */ 54 public static final int SEND_TRANSACTION = 2; 55 /** 56 * Identifies send read report requests. 57 */ 58 public static final int READREC_TRANSACTION = 3; 59 Transaction(Context context, int serviceId, TransactionSettings settings)60 public Transaction(Context context, int serviceId, 61 TransactionSettings settings) { 62 mContext = context; 63 mTransactionState = new TransactionState(); 64 mServiceId = serviceId; 65 mTransactionSettings = settings; 66 } 67 68 /** 69 * Returns the transaction state of this transaction. 70 * 71 * @return Current state of the Transaction. 72 */ 73 @Override getState()74 public TransactionState getState() { 75 return mTransactionState; 76 } 77 78 /** 79 * An instance of Transaction encapsulates the actions required 80 * during a MMS Client transaction. 81 */ process()82 public abstract void process(); 83 84 /** 85 * Used to determine whether a transaction is equivalent to this instance. 86 * 87 * @param transaction the transaction which is compared to this instance. 88 * @return true if transaction is equivalent to this instance, false otherwise. 89 */ isEquivalent(Transaction transaction)90 public boolean isEquivalent(Transaction transaction) { 91 return getClass().equals(transaction.getClass()) 92 && mId.equals(transaction.mId); 93 } 94 95 /** 96 * Get the service-id of this transaction which was assigned by the framework. 97 * @return the service-id of the transaction 98 */ getServiceId()99 public int getServiceId() { 100 return mServiceId; 101 } 102 getConnectionSettings()103 public TransactionSettings getConnectionSettings() { 104 return mTransactionSettings; 105 } setConnectionSettings(TransactionSettings settings)106 public void setConnectionSettings(TransactionSettings settings) { 107 mTransactionSettings = settings; 108 } 109 110 /** 111 * A common method to send a PDU to MMSC. 112 * 113 * @param pdu A byte array which contains the data of the PDU. 114 * @return A byte array which contains the response data. 115 * If an HTTP error code is returned, an IOException will be thrown. 116 * @throws IOException if any error occurred on network interface or 117 * an HTTP error code(>=400) returned from the server. 118 */ sendPdu(byte[] pdu)119 protected byte[] sendPdu(byte[] pdu) throws IOException { 120 return sendPdu(SendingProgressTokenManager.NO_TOKEN, pdu, 121 mTransactionSettings.getMmscUrl()); 122 } 123 124 /** 125 * A common method to send a PDU to MMSC. 126 * 127 * @param pdu A byte array which contains the data of the PDU. 128 * @param mmscUrl Url of the recipient MMSC. 129 * @return A byte array which contains the response data. 130 * If an HTTP error code is returned, an IOException will be thrown. 131 * @throws IOException if any error occurred on network interface or 132 * an HTTP error code(>=400) returned from the server. 133 */ sendPdu(byte[] pdu, String mmscUrl)134 protected byte[] sendPdu(byte[] pdu, String mmscUrl) throws IOException { 135 return sendPdu(SendingProgressTokenManager.NO_TOKEN, pdu, mmscUrl); 136 } 137 138 /** 139 * A common method to send a PDU to MMSC. 140 * 141 * @param token The token to identify the sending progress. 142 * @param pdu A byte array which contains the data of the PDU. 143 * @return A byte array which contains the response data. 144 * If an HTTP error code is returned, an IOException will be thrown. 145 * @throws IOException if any error occurred on network interface or 146 * an HTTP error code(>=400) returned from the server. 147 */ sendPdu(long token, byte[] pdu)148 protected byte[] sendPdu(long token, byte[] pdu) throws IOException { 149 return sendPdu(token, pdu, mTransactionSettings.getMmscUrl()); 150 } 151 152 /** 153 * A common method to send a PDU to MMSC. 154 * 155 * @param token The token to identify the sending progress. 156 * @param pdu A byte array which contains the data of the PDU. 157 * @param mmscUrl Url of the recipient MMSC. 158 * @return A byte array which contains the response data. 159 * If an HTTP error code is returned, an IOException will be thrown. 160 * @throws IOException if any error occurred on network interface or 161 * an HTTP error code(>=400) returned from the server. 162 */ sendPdu(long token, byte[] pdu, String mmscUrl)163 protected byte[] sendPdu(long token, byte[] pdu, String mmscUrl) throws IOException { 164 ensureRouteToHost(mmscUrl, mTransactionSettings); 165 return HttpUtils.httpConnection( 166 mContext, token, 167 mmscUrl, 168 pdu, HttpUtils.HTTP_POST_METHOD, 169 mTransactionSettings.isProxySet(), 170 mTransactionSettings.getProxyAddress(), 171 mTransactionSettings.getProxyPort()); 172 } 173 174 /** 175 * A common method to retrieve a PDU from MMSC. 176 * 177 * @param url The URL of the message which we are going to retrieve. 178 * @return A byte array which contains the data of the PDU. 179 * If the status code is not correct, an IOException will be thrown. 180 * @throws IOException if any error occurred on network interface or 181 * an HTTP error code(>=400) returned from the server. 182 */ getPdu(String url)183 protected byte[] getPdu(String url) throws IOException { 184 ensureRouteToHost(url, mTransactionSettings); 185 return HttpUtils.httpConnection( 186 mContext, SendingProgressTokenManager.NO_TOKEN, 187 url, null, HttpUtils.HTTP_GET_METHOD, 188 mTransactionSettings.isProxySet(), 189 mTransactionSettings.getProxyAddress(), 190 mTransactionSettings.getProxyPort()); 191 } 192 193 /** 194 * Make sure that a network route exists to allow us to reach the host in the 195 * supplied URL, and to the MMS proxy host as well, if a proxy is used. 196 * @param url The URL of the MMSC to which we need a route 197 * @param settings Specifies the address of the proxy host, if any 198 * @throws IOException if the host doesn't exist, or adding the route fails. 199 */ ensureRouteToHost(String url, TransactionSettings settings)200 private void ensureRouteToHost(String url, TransactionSettings settings) throws IOException { 201 ConnectivityManager connMgr = 202 (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); 203 204 int inetAddr; 205 if (settings.isProxySet()) { 206 String proxyAddr = settings.getProxyAddress(); 207 inetAddr = NetworkUtils.lookupHost(proxyAddr); 208 if (inetAddr == -1) { 209 throw new IOException("Cannot establish route for " + url + ": Unknown host"); 210 } else { 211 if (!connMgr.requestRouteToHost( 212 ConnectivityManager.TYPE_MOBILE_MMS, inetAddr)) { 213 throw new IOException("Cannot establish route to proxy " + inetAddr); 214 } 215 } 216 } else { 217 Uri uri = Uri.parse(url); 218 inetAddr = NetworkUtils.lookupHost(uri.getHost()); 219 if (inetAddr == -1) { 220 throw new IOException("Cannot establish route for " + url + ": Unknown host"); 221 } else { 222 if (!connMgr.requestRouteToHost( 223 ConnectivityManager.TYPE_MOBILE_MMS, inetAddr)) { 224 throw new IOException("Cannot establish route to " + inetAddr + " for " + url); 225 } 226 } 227 } 228 } 229 230 @Override toString()231 public String toString() { 232 return getClass().getName() + ": serviceId=" + mServiceId; 233 } 234 235 /** 236 * Get the type of the transaction. 237 * 238 * @return Transaction type in integer. 239 */ getType()240 abstract public int getType(); 241 } 242