/* * 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, } }