MMS-IOT Notifications go to wrong MMSC
[0xdroid:packages_apps_mms.git] / src / com / android / mms / transaction / Transaction.java
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
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
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      */
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      */
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      */
99     public int getServiceId() {
100         return mServiceId;
101     }
102
103     public TransactionSettings getConnectionSettings() {
104         return mTransactionSettings;
105     }
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      */
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      */
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      */
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      */
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      */
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      */
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
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      */
240     abstract public int getType();
241 }