blob: 0d49a60f77a096c2cf6b7d33fc2890a9122332e2 [file] [log] [blame]
/*
* Copyright (C) 2007-2008 Esmertec AG.
* Copyright (C) 2007-2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.im.imps;
import java.util.Map;
import com.android.im.engine.ConnectionConfig;
import com.android.im.engine.ImException;
import com.android.im.imps.ImpsConstants.ImpsVersion;
import com.android.im.plugin.ImpsConfigNames;
import com.android.im.plugin.PasswordDigest;
import com.android.im.plugin.PresenceMapping;
/**
* The configuration for IMPS connection.
*/
public class ImpsConnectionConfig extends ConnectionConfig {
private static final int DEFAULT_KEEPALIVE_SECONDS = 2 * 60 * 60; // 2 hour
private static final int DEFAULT_MIN_SERVER_POLL = 30; // seconds
private static final int DEFAULT_SMS_PORT = 3590;
private static final int DEFAULT_SMS_CIR_PORT = 3716;
private static final long DEFAULT_PRESENCE_POLL_INTERVAL = 60 * 1000; // 1 minute
// DeliveryReport is good for acknowledgment but consumes 2 extra
// transactions + 1 possible CIR notification per message. Should not
// be enabled on limited/slow connections.
private static final boolean NEED_DELIVERY_REPORT = false;
private ImpsVersion mImpsVersion = ImpsVersion.IMPS_VERSION_12;
private TransportType mDataChannelBinding = TransportType.HTTP;
private CirMethod mCirChannelBinding = CirMethod.STCP;
private EncodingType mDataEncoding = EncodingType.WBXML;
private boolean mSecureLogin = true; // default to use 4-way login
private boolean mBasicPresenceOnly = false;
private String mHost = "";
private String mClientId = "JiMMY";
private String mMsisdn;
private int mUdpPort = 3717;
private int mReplyTimeout = 45 * 1000;
private String mContentType;
private String mVersionNs;
private String mTransactionNs;
private String mPresenceNs;
private PresenceMapping mPresenceMapping;
private PasswordDigest mPasswordDigest;
private String mDefaultDomain;
private String mCustomPasswordDigest;
private String mCustomPresenceMapping;
private String mPluginPath;
private Map<String, String> mOthers;
public ImpsConnectionConfig() {
setupVersionStrings();
}
public ImpsConnectionConfig(Map<String, String> map) {
String dataChannel = map.get(ImpsConfigNames.DATA_CHANNEL);
try {
mDataChannelBinding = TransportType.valueOf(dataChannel);
} catch (IllegalArgumentException e) {
ImpsLog.log("Unknown DataChannel: " + dataChannel +", using HTTP");
mDataChannelBinding = TransportType.HTTP;
}
String dataEncoding = map.get(ImpsConfigNames.DATA_ENCODING);
try {
mDataEncoding = EncodingType.valueOf(dataEncoding);
} catch (IllegalArgumentException e) {
ImpsLog.log("Unknown DataEncoding: " + dataEncoding +", using WBXML");
mDataEncoding = EncodingType.WBXML;
}
String cirChannel = map.get(ImpsConfigNames.CIR_CHANNEL);
try {
mCirChannelBinding = CirMethod.valueOf(cirChannel);
} catch (IllegalArgumentException e) {
ImpsLog.log("Unknown CirChannel: " + cirChannel +", using TCP");
mCirChannelBinding = CirMethod.STCP;
}
mHost = map.get(ImpsConfigNames.HOST);
if (map.get(ImpsConfigNames.CLIENT_ID) != null) {
mClientId = map.get(ImpsConfigNames.CLIENT_ID);
}
if (map.get(ImpsConfigNames.MSISDN) != null) {
mMsisdn = map.get(ImpsConfigNames.MSISDN);
}
if (map.get(ImpsConfigNames.SECURE_LOGIN) != null) {
mSecureLogin = isTrue(map.get(ImpsConfigNames.SECURE_LOGIN));
}
if (map.get(ImpsConfigNames.BASIC_PA_ONLY) != null) {
mBasicPresenceOnly = isTrue(map.get(ImpsConfigNames.BASIC_PA_ONLY));
}
if (map.containsKey(ImpsConfigNames.VERSION)) {
mImpsVersion = ImpsVersion.fromString(
map.get(ImpsConfigNames.VERSION));
}
setupVersionStrings();
mDefaultDomain = map.get(ImpsConfigNames.DEFAULT_DOMAIN);
mPluginPath = map.get(ImpsConfigNames.PLUGIN_PATH);
mCustomPasswordDigest = map.get(ImpsConfigNames.CUSTOM_PASSWORD_DIGEST);
mCustomPresenceMapping = map.get(ImpsConfigNames.CUSTOM_PRESENCE_MAPPING);
mOthers = map;
}
@Override
public String getProtocolName() {
return "IMPS";
}
private void setupVersionStrings() {
if (mImpsVersion == ImpsVersion.IMPS_VERSION_11) {
if (mDataEncoding == EncodingType.XML) {
mContentType = "application/vnd.wv.csp.xml";
} else if (mDataEncoding == EncodingType.WBXML) {
mContentType = "application/vnd.wv.csp.wbxml";
} else if (mDataEncoding == EncodingType.SMS) {
mContentType = "application/vnd.wv.csp.sms";
}
mVersionNs = ImpsConstants.VERSION_11_NS;
mTransactionNs = ImpsConstants.TRANSACTION_11_NS;
mPresenceNs = ImpsConstants.PRESENCE_11_NS;
} else if (mImpsVersion == ImpsVersion.IMPS_VERSION_12) {
if (mDataEncoding == EncodingType.XML) {
mContentType = "application/vnd.wv.csp.xml";
} else if (mDataEncoding == EncodingType.WBXML) {
mContentType = "application/vnd.wv.csp.wbxml";
} else if (mDataEncoding == EncodingType.SMS) {
mContentType = "application/vnd.wv.csp.sms";
}
mVersionNs = ImpsConstants.VERSION_12_NS;
mTransactionNs = ImpsConstants.TRANSACTION_12_NS;
mPresenceNs = ImpsConstants.PRESENCE_12_NS;
} else if (mImpsVersion == ImpsVersion.IMPS_VERSION_13){
if (mDataEncoding == EncodingType.XML) {
mContentType = "application/vnd.wv.csp+xml";
} else if (mDataEncoding == EncodingType.WBXML) {
mContentType = "application/vnd.wv.csp+wbxml";
} else if (mDataEncoding == EncodingType.SMS) {
mContentType = "application/vnd.wv.csp.sms";
}
mVersionNs = ImpsConstants.VERSION_13_NS;
mTransactionNs = ImpsConstants.TRANSACTION_13_NS;
mPresenceNs = ImpsConstants.PRESENCE_13_NS;
}
}
public String getClientId() {
return mClientId;
}
public String getMsisdn() {
return mMsisdn;
}
public boolean use4wayLogin() {
return mSecureLogin;
}
public boolean useSmsAuth() {
return isTrue(mOthers.get(ImpsConfigNames.SMS_AUTH));
}
public boolean needDeliveryReport() {
return NEED_DELIVERY_REPORT;
}
/**
* Gets the type of protocol binding for data channel.
*
* @return the type of protocol binding for data channel.
*/
public TransportType getDataChannelBinding() {
return mDataChannelBinding;
}
/**
* Gets the type of protocol binding for CIR channel.
*
* @return the type of protocol binding for CIR channel.
*/
public CirMethod getCirChannelBinding() {
return mCirChannelBinding;
}
/**
* Gets the host name of the server.
*
* @return the host name of the server.
*/
public String getHost() {
return mHost;
}
/**
* Sets the host name of the server.
*
* @param host the host name.
*/
public void setHost(String host) {
mHost = host;
}
/**
* Gets the number of milliseconds to wait for a response from the server.
* The default value is 45 seconds.
*
* @return the milliseconds to wait for a response from the server
*/
public int getReplyTimeout() {
return mReplyTimeout;
}
/**
* XXX: Workaround for the OZ IMPS GTalk server which supports only basic
* presence attributes and don't support GetAttributeList.
*
* @return <code>true</code> if only basic presence attribute is
* supported.
*/
public boolean supportBasicPresenceOnly() {
return mBasicPresenceOnly;
}
public String getTransportContentType() {
return mContentType;
}
public ImpsVersion getImpsVersion() {
return mImpsVersion;
}
// TODO: should remove this and let the serializer to handle all the name
// spaces.
public String getPresenceNs() {
return mPresenceNs;
}
public PrimitiveParser createPrimitiveParser() throws ImException {
if(mDataEncoding == EncodingType.WBXML) {
return new WbxmlPrimitiveParser();
} else if (mDataEncoding == EncodingType.XML) {
return new XmlPrimitiveParser();
} else if (mDataEncoding == EncodingType.SMS) {
return new PtsPrimitiveParser();
}
ImpsLog.log("Unknown DataEncoding: " + mDataEncoding);
return null;
}
public PrimitiveSerializer createPrimitiveSerializer() {
if(mDataEncoding == EncodingType.WBXML) {
return new WbxmlPrimitiveSerializer(mImpsVersion,
mVersionNs, mTransactionNs);
} else if (mDataEncoding == EncodingType.XML) {
return new XmlPrimitiveSerializer(mVersionNs, mTransactionNs);
} else if (mDataEncoding == EncodingType.SMS) {
try {
return new PtsPrimitiveSerializer(mImpsVersion);
} catch (SerializerException e) {
ImpsLog.logError(e);
return null;
}
}
ImpsLog.log("Unknown DataEncoding: " + mDataEncoding);
return null;
}
/**
* Gets the port number for the standalone UDP/IP CIR method. This is only
* useful when UDP CIR method is used. The default port number is 3717.
*
* @return the port number for the standalone UDP/IP CIR method.
*/
public int getUdpPort() {
return mUdpPort;
}
public String getSmsAddr() {
return mOthers.get(ImpsConfigNames.SMS_ADDR);
}
public int getSmsPort() {
String value = mOthers.get(ImpsConfigNames.SMS_PORT);
if (value == null) {
return DEFAULT_SMS_PORT;
}
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
return DEFAULT_SMS_PORT;
}
}
public String getSmsCirAddr() {
return mOthers.get(ImpsConfigNames.SMS_CIR_ADDR);
}
public int getSmsCirPort() {
String value = mOthers.get(ImpsConfigNames.SMS_CIR_PORT);
if (value == null) {
return DEFAULT_SMS_CIR_PORT;
}
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
return DEFAULT_SMS_CIR_PORT;
}
}
public boolean usePrensencePolling() {
String value = mOthers.get(ImpsConfigNames.POLL_PRESENCE);
return isTrue(value);
}
public long getPresencePollInterval() {
String value = mOthers.get(ImpsConfigNames.PRESENCE_POLLING_INTERVAL);
if (value == null) {
return DEFAULT_PRESENCE_POLL_INTERVAL;
}
try {
return Long.parseLong(value);
} catch (NumberFormatException e) {
return DEFAULT_PRESENCE_POLL_INTERVAL;
}
}
public int getDefaultServerPollMin() {
return DEFAULT_MIN_SERVER_POLL;
}
public int getDefaultKeepAliveInterval() {
return DEFAULT_KEEPALIVE_SECONDS;
}
public PresenceMapping getPresenceMapping() {
if (mPresenceMapping != null) {
return mPresenceMapping;
}
if (mCustomPresenceMapping != null) {
try {
mPresenceMapping = new CustomPresenceMapping(mPluginPath,
mCustomPresenceMapping);
} catch (ImException e) {
ImpsLog.logError("Failed to load custom presence mapping", e);
}
}
if (mPresenceMapping == null) {
mPresenceMapping = new DefaultPresenceMapping();
}
return mPresenceMapping;
}
public PasswordDigest getPasswordDigest() {
if (mPasswordDigest != null) {
return mPasswordDigest;
}
if (mCustomPasswordDigest != null) {
try {
mPasswordDigest = new CustomPasswordDigest(mPluginPath, mCustomPasswordDigest);
} catch (ImException e) {
ImpsLog.logError("Can't load custom password digest method", e);
}
}
if (mPasswordDigest == null) {
mPasswordDigest = new StandardPasswordDigest();
}
return mPasswordDigest;
}
public String getDefaultDomain() {
return mDefaultDomain;
}
private boolean isTrue(String value) {
return "true".equalsIgnoreCase(value);
}
/**
* Represents the type of protocol binding for data channel.
*/
public static enum TransportType {
WAP, HTTP, HTTPS, SMS,
}
/**
* Represents the type of the data encoding.
*/
public static enum EncodingType {
XML, WBXML, SMS,
}
/**
* Represents the type of protocol binding for CIR channel.
*/
public static enum CirMethod {
/**
* WAP 1.2 or WAP 2.0 push using WSP unit push message and SMS as a
* bearer
*/
WAPSMS,
/**
* WAP 1.2 or WAP 2.0 push using WSP unit push message and UDP/IP as a
* bearer
*/
WAPUDP,
/**
* Standalone SMS binding
*/
SSMS,
/**
* Standalone UDP/IP binding
*/
SUDP,
/**
* Standalone TCP/IP binding
*/
STCP,
/**
* Standalone HTTP binding
*/
SHTTP,
/**
* No CIR channel
*/
NONE,
}
}