/* * Funambol is a mobile platform developed by Funambol, Inc. * Copyright (C) 2003 - 2007 Funambol, Inc. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by * the Free Software Foundation with the addition of the following permission * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License * along with this program; if not, see http://www.gnu.org/licenses or write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA. * * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License * version 3, these Appropriate Legal Notices must retain the display of the * "Powered by Funambol" logo. If the display of the logo is not reasonably * feasible for technical reasons, the Appropriate Legal Notices must display * the words "Powered by Funambol". */ package com.funambol.util; import java.util.Hashtable; /** * Connection Configurations repository: this class is needed to configure the * connections using the carrier parameters in order to access the network. * Configurations are useful both for socket and Http connections. * It should be suitable that every class that perform a call to the open method * of the javax.microedition.io.Connetor class use this class in oder to have * working configurations loaded when the application runs. This class is mostly * used into the Blackberry implementation as the device doesn't allow simple * URL request to be sent on the network without APN or interface parameters. * For more information about this topic see the Blackberry developers guide. */ public class ConnectionConfig { /**Maximum configurations number*/ protected static final int MAX_CONFIG_NUMBER = 5; /**-1: No config has been set*/ protected static final int CONFIG_NONE = -1; /**0: Wifi configurations index*/ protected static final int WIFI_CONFIG = 0; /**1: TCP user's defined configurations index*/ protected static final int TCP_CONFIG = 1; /**2: Apn table - APNGateway class defined - configurations index*/ protected static final int APN_TABLE_CONFIG = 2; /**3: Service book configurations index*/ protected static final int SERVICE_BOOK_CONFIG = 3; /**4: BES configuration index */ protected static final int BES_CONFIG = 4; /**Description when no config has been set*/ protected static final String CONFIG_NONE_DESCRIPTION = "No working config found"; /**WIFI configuration description*/ protected static final String WIFI_CONFIG_DESCRIPTION = "Wifi Network"; /**TCP user's defined configurations description*/ protected static final String TCP_CONFIG_DESCRIPTION = "User defined TCP Configuration"; /**Apn table - APNGateway class defined - configurations description*/ protected static final String APN_TABLE_CONFIG_DESCRIPTION = "Client APN table defined configuration"; /**Service book configurations description*/ protected static final String SERVICE_BOOK_CONFIG_DESCRIPTION = "Service book Configuration"; /**Straight connection - works only with BES */ protected static final String BES_CONFIG_DESCRIPTION = "BES Configuration"; /**BASIC custom APN configuration parameters*/ private static String BASE_CONFIG_PARAMETERS = ";deviceside=true"; /**WIFI custom URL configuration parameters*/ private static String WIFI_CONFIG_PARAMETERS = ";interface=wifi"; /**BES APN configuration parameters*/ private static String BES_CONFIG_PARAMETERS = ""; /**1: Permission denied value*/ protected static final int PERMISSION_DENIED = 1; /**0: Permission granted value*/ protected static final int PERMISSION_GRANTED = 0; /**-1: Permission undefined value*/ protected static final int PERMISSION_UNDEFINED = -1; /**Empty String: Value to initialize the configurations parameters*/ protected static final String NO_PARAMETERS = ""; /**Empty String: Value to initialize the configurations Descriptions*/ protected static final String NO_DESCRIPTION = ""; /**US Country selector*/ private static final String COUNTRY_US = "US"; /**IT country selector*/ private static final String COUNTRY_IT = "IT"; /**DE country selector*/ private static final String COUNTRY_DE = "DE"; /**UK country selector*/ private static final String COUNTRY_UK = "UK"; /**EGYPT country selector*/ private static final String COUNTRY_EGYPT = "EGYPT"; /**ALGERIA country selector*/ private static final String COUNTRY_ALGERIA = "ALGERIA"; /**BANGLADESH country selector*/ private static final String COUNTRY_BANGLADESH = "BANGLADESH"; /**GREECE country selector*/ private static final String COUNTRY_GREECE = "GREECE"; /**PAKISTAN country selector*/ private static final String COUNTRY_PAKISTAN = "PAKISTAN"; /** ARAB EMIRATES */ private static final String COUNTRY_AE = "AE"; /**BlackberryConfiguration array*/ private static BlackberryConfiguration[] configurations = null; /**Hashtable used to store the APN list*/ private static Hashtable apnTable = new Hashtable(); static { //Statically fill the ApnTable hashtable initApnTable(); //Statically fill all of the available BlackberryConfigurations init(); } /** * Accessor Method to get the configuration availability run-time * @return true if the device bearer */ public static boolean isAvailable(int configuration) { switch (configuration) { case WIFI_CONFIG: return (BlackberryUtils.isWifiActive()&&BlackberryUtils.isWifiAvailable()); case TCP_CONFIG: case APN_TABLE_CONFIG: case SERVICE_BOOK_CONFIG: case BES_CONFIG: return !BlackberryUtils.isWapGprsDataBearerOffline(); default: break; } return false; } /** * Returns true if the given configuration works through a BIS * or carrier APN (direct tcp) */ public static boolean isDirectTCP(int configuration) { return (configuration == TCP_CONFIG || configuration == APN_TABLE_CONFIG || configuration == SERVICE_BOOK_CONFIG); } /** * Returns the id of the BES configuration if defined. -1 otherwise. */ public static int getBESConfigurationID() { return BES_CONFIG; } /** * Get the available configurations array * @return BlackberryConfiguration[] representing the array with the * available configurations */ protected static BlackberryConfiguration[] getBlackberryConfigurations() { //It is better to perform this operation because some VM //implementation could have a different behavior for static addressed //classes in particular it could happen that the configuration //permission would not be initialized when an application starts, but //only when the application is installed the first time //The same call of static the block that Statically filled the ApnTable //hashtable //initApnTable(); //The same call of static the block that Statically filled all of the //available BlackberryConfigurations //init(); //Return the initialized BlackberryConfiguration array Log.debug("[ConnectionConfig.getBlackberryConfigurations]Returning Configurations"); Log.debug(getConfigsDescription()); Log.debug(getWorkingConfigurationDescription()); return configurations; } /** * Check if the data connection provider is US based * @return true if an US carrier APN is found in the address book */ protected static boolean isUSCarrier() { Log.debug("[ConnectionConfig.isUSCarrier] Checking if we're in US"); String[] serviceBookApn = BlackberryUtils.getAllActiveServiceBookAPNs(); boolean isUsCountry = false; if (serviceBookApn != null) { Log.trace("[ConnectionConfig.isUSCarrier]ServiceBook APN is not null"); WapGateway gateway = findGatewayByApn(serviceBookApn); if (gateway != null) { Log.trace("[ConnectionConfig.isUSCarrier]Gateway is not null"); Log.trace("[ConnectionConfig.isUSCarrier]APN: " + gateway.getApn()); Log.trace("[ConnectionConfig.isUSCarrier]Username: " + gateway.getUsername()); Log.trace("[ConnectionConfig.isUSCarrier]Password: " + gateway.getPassword()); Log.trace("[ConnectionConfig.isUSCarrier]Country: " + gateway.getCountry()); //if in us return false isUsCountry = COUNTRY_US.equals(gateway.getCountry()); Log.trace("[ConnectionConfig.isUSCarrier]US Country check: " + isUsCountry); return isUsCountry; } else { Log.trace("[ConnectionConfig.isUSCarrier]Gateway is NULL"); } } else { Log.trace("[ConnectionConfig.isUSCarrier]ServiceBook APN is NULL"); } Log.debug("[ConnectionConfig.isUSCarrier]Final value returned by: " + isUsCountry + " for " + serviceBookApn); return isUsCountry; } /** * Look up the apntable to find the right wapgateway apnList, * username and password to use with current network. * @return String formatted APN and authentication related parameters to be * added on the request url */ private static String getAPNGatewayOptions() { StringBuffer options = new StringBuffer(""); String[] serviceBookApn = BlackberryUtils.getAllActiveServiceBookAPNs(); Log.debug("[ConnectionConfig]Trying to find gateway for APN: " + serviceBookApn); if (serviceBookApn != null) { WapGateway gateway = findGatewayByApn(serviceBookApn); if (gateway != null) { //We matched with a gateway in our list. Build connection options options.append(";apn=" + gateway.getApn()); options.append(";WapGatewayAPN=" + gateway.getApn()); if (gateway.getUsername() != null) { options.append(";TunnelAuthUsername=" + gateway.getUsername()); } if (gateway.getPassword() != null) { options.append(";TunnelAuthPassword=" + gateway.getPassword()); } if (gateway.getGatewayIP() != null) { options.append(";WapGatewayIP=" + gateway.getGatewayIP()); } } } return options.toString(); } /** * Retrieves the APN for the given configuration * @param configId the configuration index * @return the String formatted APN */ protected static String getAPNFromConfig(int configId) { if (configId == WIFI_CONFIG) { Log.debug("[ConnectionManager.isConfigurationAllowed]Returning wifi configuration description"); return WIFI_CONFIG_DESCRIPTION; } if (configId == TCP_CONFIG) { Log.debug("[ConnectionManager.isConfigurationAllowed]Returning TCP configuration description"); return TCP_CONFIG_DESCRIPTION; } if (configId == SERVICE_BOOK_CONFIG) { Log.debug("[ConnectionManager.isConfigurationAllowed]Returning Service book configuration"); return BlackberryUtils.getServiceBookWapTransportApn(); } if (configId == BES_CONFIG) { Log.debug("[ConnectionManager.isConfigurationAllowed]Returning BES configuration description"); return BES_CONFIG_DESCRIPTION; } // looking for apnList String sep = ";apn="; String config = configurations[configId].getUrlParameters(); Log.debug("[ConnectionConfig]Configuration found: " + config); int start = config.indexOf(sep); if (start == -1) { Log.debug("[ConnectionConfig]APN not found: Returning NULL"); return null; } start += sep.length(); int stop = config.substring(start).indexOf(";"); Log.debug("[ConnectionConfig]start= " + start + " stop= " + stop); if (stop == -1) { return config.substring(start); } else { return config.substring(start, start + stop); } } /** * Look into the apntable to find the correct gateway given the apnList. * A gateway is composed by apnList, username and password. * @param apnList the apnList to look for * @return the correct gateway object. Note that given an apnList, tha gateway may * use a different apnList, e.g. given wap.tim.it the returned gateway has * ibox.tim.it as apnList, this is due to the fact that some apns does not allow * tcp communications */ private static WapGateway findGatewayByApn(String[] apnList) { for (int i = 0; i < apnList.length; i++) { if (apnList[i] != null) { WapGateway ret = (WapGateway) apnTable.get(apnList[i].toLowerCase()); if (ret != null) { Log.debug("[ConnectionConfig]ApnTable returned " + ret.getApn() + " for apn " + apnList[i]); return ret; } else { Log.debug("[ConnectionConfig]ApnTable found no entry for apn " + apnList[i]); } } } Log.info("[ConnectionConfig] apnTable entry not found... returning null"); return null; } /** * Initializes the ApnTable hashtable with the predefined values */ private static void initApnTable() { // building APN table Log.debug("[ConnectionConfig] creating apn table..."); //------------------------- //------ US OPERATORS ----- //------------------------- //------------------------- // ATT Orange (Cingular) //------------------------- apnTable.put("wap.cingular", new WapGateway("wap.cingular", "WAP@CINGULARGPRS.COM", "CINGULAR1", COUNTRY_US)); //------------------------- //T-Mobile US1 //------------------------- apnTable.put("internet2.voicestream.com", new WapGateway("internet2.voicestream.com", null, null, COUNTRY_US)); //------------------------- //T-Mobile US2 //------------------------- apnTable.put("wap.voicestream.com", new WapGateway("wap.voicestream.com", null, null, COUNTRY_US)); //------------------------- //Sprint: // NOTE: should be internet.com but there could be other parameters //------------------------- apnTable.put("internet.com", new WapGateway("internet.com", null, null, COUNTRY_US)); //------------------------- //Verizon: should work with no apnList //------------------------- //------------------------- // ---- IT OPERATORS ---- // //------------------------- //------------------------- //Tim, both gprs and wap //------------------------- WapGateway tim = new WapGateway("ibox.tim.it", null, null, COUNTRY_IT); apnTable.put("ibox.tim.it", tim); apnTable.put("wap.tim.it", tim); //------------------------- // Wind //------------------------- WapGateway wind = new WapGateway("internet.wind", null, null, COUNTRY_IT); apnTable.put("internet.wind", wind); apnTable.put("internet.wind.biz", wind); apnTable.put("wap.wind.biz", wind); //------------------------- // Omnitel (Vodafone IT) //------------------------- WapGateway omni = new WapGateway("web.omnitel.it", null, null, COUNTRY_IT); apnTable.put("web.omnitel.it", omni); apnTable.put("wap.omnitel.it", omni); //------------------------- // ---- German OPERATORS ---- // //------------------------- //------------------------- // Vodafone DE, wap //------------------------- WapGateway vodafoneDe = new WapGateway("wap.vodafone.de", null, null, "139.7.29.1", COUNTRY_DE); apnTable.put("wap.vodafone.de", vodafoneDe); //------------------------- // ---- UK OPERATORS ---- // //------------------------- //------------------------- // BT //------------------------- WapGateway btUK = new WapGateway("btmobile.bt.com", "bt", "bt", COUNTRY_UK); apnTable.put("btmobile.bt.com", btUK); //------------------------------- // // ---- Egyptian OPERATORS ---- // //------------------------------- // WapGateway vodafoneEgypt = new WapGateway( "internet.Vodafone.net", "internet", "internet", COUNTRY_EGYPT); apnTable.put("internet.Vodafone.net", vodafoneEgypt); WapGateway mobiNilEgypt = new WapGateway( "mobinilweb", null, null, COUNTRY_EGYPT); apnTable.put("mobinilweb", mobiNilEgypt); WapGateway etilaSat = new WapGateway( "etilasat", null, null, COUNTRY_EGYPT); apnTable.put("etilasat", etilaSat); //------------------------------- // // ---- Algerian OPERATORS ---- // //------------------------------- // WapGateway djezzy = new WapGateway( "djezzy.internet", null, null, COUNTRY_ALGERIA); apnTable.put("djezzy.internet", djezzy); //------------------------------- // // ---- Bangladesh OPERATORS ---- // //------------------------------- // WapGateway banglaLink = new WapGateway( "blweb", null, null, COUNTRY_BANGLADESH); apnTable.put("blweb", banglaLink); //------------------------------- // // ---- Greek OPERATORS ---- // //------------------------------- // WapGateway windGR = new WapGateway( "gint.b-online.gr", null, null, COUNTRY_GREECE); apnTable.put("gint.b-online.gr", windGR); //------------------------------- // // ---- Pakistan OPERATORS ---- // //------------------------------- // WapGateway mobilink = new WapGateway( "connect.mobilinkworld.com", null, null, COUNTRY_PAKISTAN); apnTable.put("connect.mobilinkworld.com", mobilink); //------------------------- // ---- Arab Emirates OPERATORS ---- // //------------------------- //------------------------- // DU //------------------------- WapGateway du = new WapGateway("du", null, null, COUNTRY_AE); apnTable.put("du", du); Log.debug("[ConnectionConfig] apntable created"); } /** * Initializes the static BlackBerryConfigurations array */ private static void init() { Log.info("[ConnectionConfig.init] init configs"); /////////////////////////////////////////////////////// // Initialize the configurations arrays /////////////////////////////////////////////////////// configurations = new BlackberryConfiguration[MAX_CONFIG_NUMBER]; for (int j = 0; j < configurations.length; ++j) { configurations[j] = new BlackberryConfiguration(); configurations[j].setUrlParameters(NO_PARAMETERS); configurations[j].setDescription(NO_DESCRIPTION); configurations[j].setPermission(PERMISSION_UNDEFINED); } /////////////////////////////////////////////////////// //WIFI Settings /////////////////////////////////////////////////////// int configurationID = WIFI_CONFIG; configurations[configurationID].setUrlParameters(WIFI_CONFIG_PARAMETERS); configurations[configurationID].setDescription(WIFI_CONFIG_DESCRIPTION); //Grants automatically wifi connections only if Wifi Bearer is present on the device if (BlackberryUtils.isWifiAvailable()) { configurations[WIFI_CONFIG].setPermission(PERMISSION_GRANTED); } else { configurations[WIFI_CONFIG].setPermission(PERMISSION_DENIED); } /////////////////////////////////////////////////////// //TCP Settings /////////////////////////////////////////////////////// configurations[TCP_CONFIG].setUrlParameters(BASE_CONFIG_PARAMETERS); configurations[TCP_CONFIG].setDescription(TCP_CONFIG_DESCRIPTION); //Grants automatically connections for specific TCP setting //manually set by the user in the Options -> Advanced Options -> TCP //device's configuration screen configurations[TCP_CONFIG].setPermission(PERMISSION_GRANTED); /////////////////////////////////////////////////////// //Custom APNGateway table defined into the static block /////////////////////////////////////////////////////// configurations[APN_TABLE_CONFIG].setUrlParameters(BASE_CONFIG_PARAMETERS + getAPNGatewayOptions()); configurations[APN_TABLE_CONFIG].setDescription(APN_TABLE_CONFIG_DESCRIPTION); //Permission previously set to undefined /////////////////////////////////////////////////////// //Device's ServiceBook content related configurations /////////////////////////////////////////////////////// configurations[SERVICE_BOOK_CONFIG].setUrlParameters(BASE_CONFIG_PARAMETERS + BlackberryUtils.getServiceBookOptions()); configurations[SERVICE_BOOK_CONFIG].setDescription(SERVICE_BOOK_CONFIG_DESCRIPTION); /////////////////////////////////////////////////////// //BES Settings /////////////////////////////////////////////////////// Log.debug("Setting BES Config " + BES_CONFIG + " " + BES_CONFIG_PARAMETERS + " " + BES_CONFIG_DESCRIPTION); configurations[BES_CONFIG].setUrlParameters(BES_CONFIG_PARAMETERS); configurations[BES_CONFIG].setDescription(BES_CONFIG_DESCRIPTION); //Grants automatically connections for BES configuration configurations[BES_CONFIG].setPermission(PERMISSION_GRANTED); //Permission previously set to undefined Log.info("[ConnectionConfig] Configs created"); } /** * Refresh the configuration parameters. Useful when the servicebook changed */ protected static void refreshServiceBookConfigurations() { configurations[APN_TABLE_CONFIG].setUrlParameters(BASE_CONFIG_PARAMETERS + getAPNGatewayOptions()); configurations[SERVICE_BOOK_CONFIG].setUrlParameters(BASE_CONFIG_PARAMETERS + BlackberryUtils.getServiceBookOptions()); } /** * Get the description related to the given configurations index * @param configId the configurations index * @return String description for the given configurations index */ protected static String getConfigurationDescription(int configId) { return configurations[configId].getDescription(); } /** * Get the configurations description * @return a string describing the current configurations descriptions */ public static String getConfigsDescription() { StringBuffer configs = new StringBuffer("Configurations:"); for (int i = 0; i < configurations.length; i++) { configs.append("\n[" + i + "] " + configurations[i].getUrlParameters()); } return configs.toString(); } /** * Accessor method that return the current working configurations description * @return String related to the current working configurations description */ public static String getWorkingConfigurationDescription() { if (ConnectionManager.workingConfigID == ConnectionConfig.CONFIG_NONE) { return ConnectionConfig.CONFIG_NONE_DESCRIPTION; } else { return configurations[ConnectionManager.workingConfigID].getDescription(); } } /** * Check if user must allow the APN usage. In US countries this check * returns false * @return false if the country retrieved by the service book is US, true * otherwise */ public static boolean isUserConfirmationNeeded() { Log.debug("[ConnectionManager.isUserConfirmationNeeded]User Confirmation needed value is: " + !ConnectionConfig.isUSCarrier()); return !isUSCarrier(); } /** * Remove the saved working configurations ID. This method is used when * we're unable to connect, to avoid trying the same configurations every * time. */ public static void removeSavedConfig() { Log.debug("[ConnectionManager.removeSavedConfig]Removing saved config (" + ConnectionManager.workingConfigID + ") " + getWorkingConfigurationDescription()); ConnectionManager.workingConfigID = ConnectionConfig.CONFIG_NONE; } /** * Reset all of the configurations' permission to the initial state value */ public static void resetConfigurationsPermissions() { //Reset WIFI permission checking the WIFI bearer presence and working //state if (BlackberryUtils.isWifiAvailable()) { configurations[ConnectionConfig.WIFI_CONFIG].setPermission(ConnectionConfig.PERMISSION_GRANTED); } else { configurations[ConnectionConfig.WIFI_CONFIG].setPermission(ConnectionConfig.PERMISSION_DENIED); } //Reset TCP Permission to granted configurations[ConnectionConfig.TCP_CONFIG].setPermission(ConnectionConfig.PERMISSION_GRANTED); //Reset the generated APN table permission to undefined configurations[ConnectionConfig.APN_TABLE_CONFIG].setPermission(ConnectionConfig.PERMISSION_UNDEFINED); //Reset the Service Book usage permission to undefined configurations[ConnectionConfig.SERVICE_BOOK_CONFIG].setPermission(ConnectionConfig.PERMISSION_UNDEFINED); //Reset the BES permission to granted configurations[ConnectionConfig.BES_CONFIG].setPermission(ConnectionConfig.PERMISSION_GRANTED); } }