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
18package com.android.mms.transaction;
19
20import android.content.Context;
21import android.database.Cursor;
22import android.database.sqlite.SqliteWrapper;
23import android.net.NetworkUtils;
24import android.provider.Telephony;
25import android.text.TextUtils;
26import android.util.Log;
27
28import com.android.internal.telephony.PhoneConstants;
29import com.android.mms.LogTag;
30
31/**
32 * Container of transaction settings. Instances of this class are contained
33 * within Transaction instances to allow overriding of the default APN
34 * settings or of the MMS Client.
35 */
36public class TransactionSettings {
37    private static final String TAG = "TransactionSettings";
38    private static final boolean DEBUG = true;
39    private static final boolean LOCAL_LOGV = false;
40
41    private String mServiceCenter;
42    private String mProxyAddress;
43    private int mProxyPort = -1;
44
45    private static final String[] APN_PROJECTION = {
46            Telephony.Carriers.TYPE,            // 0
47            Telephony.Carriers.MMSC,            // 1
48            Telephony.Carriers.MMSPROXY,        // 2
49            Telephony.Carriers.MMSPORT          // 3
50    };
51    private static final int COLUMN_TYPE         = 0;
52    private static final int COLUMN_MMSC         = 1;
53    private static final int COLUMN_MMSPROXY     = 2;
54    private static final int COLUMN_MMSPORT      = 3;
55
56    /**
57     * Constructor that uses the default settings of the MMS Client.
58     *
59     * @param context The context of the MMS Client
60     */
61    public TransactionSettings(Context context, String apnName) {
62        if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
63            Log.v(TAG, "TransactionSettings: apnName: " + apnName);
64        }
65        String selection = Telephony.Carriers.CURRENT + " IS NOT NULL";
66        String[] selectionArgs = null;
67        if (!TextUtils.isEmpty(apnName)) {
68            selection += " AND " + Telephony.Carriers.APN + "=?";
69            selectionArgs = new String[]{ apnName.trim() };
70        }
71
72        Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(),
73                            Telephony.Carriers.CONTENT_URI,
74                            APN_PROJECTION, selection, selectionArgs, null);
75
76        if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
77            Log.v(TAG, "TransactionSettings looking for apn: " + selection + " returned: " +
78                    (cursor ==null ? "null cursor" : (cursor.getCount() + " hits")));
79        }
80
81        if (cursor == null) {
82            Log.e(TAG, "Apn is not found in Database!");
83            return;
84        }
85
86        boolean sawValidApn = false;
87        try {
88            while (cursor.moveToNext() && TextUtils.isEmpty(mServiceCenter)) {
89                // Read values from APN settings
90                if (isValidApnType(cursor.getString(COLUMN_TYPE), PhoneConstants.APN_TYPE_MMS)) {
91                    sawValidApn = true;
92
93                    String mmsc = cursor.getString(COLUMN_MMSC);
94                    if (mmsc == null) {
95                        continue;
96                    }
97
98                    mServiceCenter = NetworkUtils.trimV4AddrZeros(mmsc.trim());
99                    mProxyAddress = NetworkUtils.trimV4AddrZeros(
100                            cursor.getString(COLUMN_MMSPROXY));
101                    if (isProxySet()) {
102                        String portString = cursor.getString(COLUMN_MMSPORT);
103                        try {
104                            mProxyPort = Integer.parseInt(portString);
105                        } catch (NumberFormatException e) {
106                            if (TextUtils.isEmpty(portString)) {
107                                Log.w(TAG, "mms port not set!");
108                            } else {
109                                Log.e(TAG, "Bad port number format: " + portString, e);
110                            }
111                        }
112                    }
113                }
114            }
115        } finally {
116            cursor.close();
117        }
118
119        Log.v(TAG, "APN setting: MMSC: " + mServiceCenter + " looked for: " + selection);
120
121        if (sawValidApn && TextUtils.isEmpty(mServiceCenter)) {
122            Log.e(TAG, "Invalid APN setting: MMSC is empty");
123        }
124    }
125
126    /**
127     * Constructor that overrides the default settings of the MMS Client.
128     *
129     * @param mmscUrl The MMSC URL
130     * @param proxyAddr The proxy address
131     * @param proxyPort The port used by the proxy address
132     * immediately start a SendTransaction upon completion of a NotificationTransaction,
133     * false otherwise.
134     */
135    public TransactionSettings(String mmscUrl, String proxyAddr, int proxyPort) {
136        mServiceCenter = mmscUrl != null ? mmscUrl.trim() : null;
137        mProxyAddress = proxyAddr;
138        mProxyPort = proxyPort;
139
140        if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
141            Log.v(TAG, "TransactionSettings: " + mServiceCenter +
142                    " proxyAddress: " + mProxyAddress +
143                    " proxyPort: " + mProxyPort);
144        }
145   }
146
147    public String getMmscUrl() {
148        return mServiceCenter;
149    }
150
151    public String getProxyAddress() {
152        return mProxyAddress;
153    }
154
155    public int getProxyPort() {
156        return mProxyPort;
157    }
158
159    public boolean isProxySet() {
160        return (mProxyAddress != null) && (mProxyAddress.trim().length() != 0);
161    }
162
163    static private boolean isValidApnType(String types, String requestType) {
164        // If APN type is unspecified, assume APN_TYPE_ALL.
165        if (TextUtils.isEmpty(types)) {
166            return true;
167        }
168
169        for (String t : types.split(",")) {
170            if (t.equals(requestType) || t.equals(PhoneConstants.APN_TYPE_ALL)) {
171                return true;
172            }
173        }
174        return false;
175    }
176}
177