Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.internal.telephony;
     18 
     19 import android.app.ActivityManagerNative;
     20 import android.app.AlarmManager;
     21 import android.content.Context;
     22 import android.content.res.Configuration;
     23 import android.net.wifi.WifiManager;
     24 import android.os.Build;
     25 import android.os.RemoteException;
     26 import android.os.SystemProperties;
     27 import android.telephony.TelephonyManager;
     28 import android.text.TextUtils;
     29 import android.util.Slog;
     30 
     31 import java.util.ArrayList;
     32 import java.util.Arrays;
     33 import java.util.Collections;
     34 import java.util.List;
     35 import java.util.Locale;
     36 import libcore.icu.TimeZoneNames;
     37 
     38 /**
     39  * Mobile Country Code
     40  *
     41  * {@hide}
     42  */
     43 public final class MccTable
     44 {
     45     static final String LOG_TAG = "MccTable";
     46 
     47     static ArrayList<MccEntry> sTable;
     48 
     49     static class MccEntry implements Comparable<MccEntry>
     50     {
     51         int mMcc;
     52         String mIso;
     53         int mSmallestDigitsMnc;
     54         String mLanguage;
     55 
     56         MccEntry(int mnc, String iso, int smallestDigitsMCC) {
     57             this(mnc, iso, smallestDigitsMCC, null);
     58         }
     59 
     60         MccEntry(int mnc, String iso, int smallestDigitsMCC, String language) {
     61             mMcc = mnc;
     62             mIso = iso;
     63             mSmallestDigitsMnc = smallestDigitsMCC;
     64             mLanguage = language;
     65         }
     66 
     67 
     68         @Override
     69         public int compareTo(MccEntry o)
     70         {
     71             return mMcc - o.mMcc;
     72         }
     73     }
     74 
     75     private static MccEntry
     76     entryForMcc(int mcc)
     77     {
     78         int index;
     79 
     80         MccEntry m;
     81 
     82         m = new MccEntry(mcc, null, 0);
     83 
     84         index = Collections.binarySearch(sTable, m);
     85 
     86         if (index < 0) {
     87             return null;
     88         } else {
     89             return sTable.get(index);
     90         }
     91     }
     92 
     93     /**
     94      * Returns a default time zone ID for the given MCC.
     95      * @param mcc Mobile Country Code
     96      * @return default TimeZone ID, or null if not specified
     97      */
     98     public static String defaultTimeZoneForMcc(int mcc) {
     99         MccEntry entry;
    100 
    101         entry = entryForMcc(mcc);
    102         if (entry == null || entry.mIso == null) {
    103             return null;
    104         } else {
    105             Locale locale;
    106             if (entry.mLanguage == null) {
    107                 locale = new Locale(entry.mIso);
    108             } else {
    109                 locale = new Locale(entry.mLanguage, entry.mIso);
    110             }
    111             String[] tz = TimeZoneNames.forLocale(locale);
    112             if (tz.length == 0) return null;
    113             return tz[0];
    114         }
    115     }
    116 
    117     /**
    118      * Given a GSM Mobile Country Code, returns
    119      * an ISO two-character country code if available.
    120      * Returns "" if unavailable.
    121      */
    122     public static String
    123     countryCodeForMcc(int mcc)
    124     {
    125         MccEntry entry;
    126 
    127         entry = entryForMcc(mcc);
    128 
    129         if (entry == null) {
    130             return "";
    131         } else {
    132             return entry.mIso;
    133         }
    134     }
    135 
    136     /**
    137      * Given a GSM Mobile Country Code, returns
    138      * an ISO 2-3 character language code if available.
    139      * Returns null if unavailable.
    140      */
    141     public static String defaultLanguageForMcc(int mcc) {
    142         MccEntry entry;
    143 
    144         entry = entryForMcc(mcc);
    145 
    146         if (entry == null) {
    147             return null;
    148         } else {
    149             return entry.mLanguage;
    150         }
    151     }
    152 
    153     /**
    154      * Given a GSM Mobile Country Code, returns
    155      * the smallest number of digits that M if available.
    156      * Returns 2 if unavailable.
    157      */
    158     public static int
    159     smallestDigitsMccForMnc(int mcc)
    160     {
    161         MccEntry entry;
    162 
    163         entry = entryForMcc(mcc);
    164 
    165         if (entry == null) {
    166             return 2;
    167         } else {
    168             return entry.mSmallestDigitsMnc;
    169         }
    170     }
    171 
    172     /**
    173      * Updates MCC and MNC device configuration information for application retrieving
    174      * correct version of resources.  If MCC is 0, MCC and MNC will be ignored (not set).
    175      * @param context Context to act on.
    176      * @param mccmnc truncated imsi with just the MCC and MNC - MNC assumed to be from 4th to end
    177      * @param fromServiceState true if coming from the radio service state, false if from SIM
    178      */
    179     public static void updateMccMncConfiguration(Context context, String mccmnc,
    180             boolean fromServiceState) {
    181         Slog.d(LOG_TAG, "updateMccMncConfiguration mccmnc='" + mccmnc + "' fromServiceState=" + fromServiceState);
    182         if (!TextUtils.isEmpty(mccmnc)) {
    183             int mcc, mnc;
    184 
    185             String defaultMccMnc = TelephonyManager.getDefault().getSimOperator();
    186             Slog.d(LOG_TAG, "updateMccMncConfiguration defaultMccMnc=" + defaultMccMnc);
    187             //Update mccmnc only for default subscription in case of MultiSim.
    188 //            if (!defaultMccMnc.equals(mccmnc)) {
    189 //                Slog.d(LOG_TAG, "Not a Default subscription, ignoring mccmnc config update.");
    190 //                return;
    191 //            }
    192 
    193             try {
    194                 mcc = Integer.parseInt(mccmnc.substring(0,3));
    195                 mnc = Integer.parseInt(mccmnc.substring(3));
    196             } catch (NumberFormatException e) {
    197                 Slog.e(LOG_TAG, "Error parsing IMSI");
    198                 return;
    199             }
    200 
    201             Slog.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc);
    202 
    203             Locale locale = null;
    204             if (mcc != 0) {
    205                 setTimezoneFromMccIfNeeded(context, mcc);
    206                 locale = getLocaleFromMcc(context, mcc);
    207             }
    208             if (fromServiceState) {
    209                 setWifiCountryCodeFromMcc(context, mcc);
    210             } else {
    211                 // from SIM
    212                 try {
    213                     Configuration config = new Configuration();
    214                     boolean updateConfig = false;
    215                     if (mcc != 0) {
    216                         config.mcc = mcc;
    217                         config.mnc = mnc == 0 ? Configuration.MNC_ZERO : mnc;
    218                         updateConfig = true;
    219                     }
    220                     if (locale != null) {
    221                         config.setLocale(locale);
    222                         updateConfig = true;
    223                     }
    224                     if (updateConfig) {
    225                         Slog.d(LOG_TAG, "updateMccMncConfiguration updateConfig config=" + config);
    226                         ActivityManagerNative.getDefault().updateConfiguration(config);
    227                     } else {
    228                         Slog.d(LOG_TAG, "updateMccMncConfiguration nothing to update");
    229                     }
    230                 } catch (RemoteException e) {
    231                     Slog.e(LOG_TAG, "Can't update configuration", e);
    232                 }
    233             }
    234         } else {
    235             if (fromServiceState) {
    236                 // an empty mccmnc means no signal - tell wifi we don't know
    237                 setWifiCountryCodeFromMcc(context, 0);
    238             }
    239         }
    240     }
    241 
    242     /**
    243      * Return Locale for the language and country or null if no good match.
    244      *
    245      * @param context Context to act on.
    246      * @param language Two character language code desired
    247      * @param country Two character country code desired
    248      *
    249      * @return Locale or null if no appropriate value
    250      */
    251     public static Locale getLocaleForLanguageCountry(Context context, String language,
    252             String country) {
    253         if (language == null) {
    254             Slog.d(LOG_TAG, "getLocaleForLanguageCountry: skipping no language");
    255             return null; // no match possible
    256         }
    257         if (country == null) {
    258             country = ""; // The Locale constructor throws if passed null.
    259         }
    260 
    261         // Note: persist.always.persist.locale actually means the opposite!
    262         boolean alwaysPersist = false;
    263         if (Build.IS_DEBUGGABLE) {
    264             alwaysPersist = SystemProperties.getBoolean("persist.always.persist.locale", false);
    265         }
    266         String persistSysLanguage = SystemProperties.get("persist.sys.language", "");
    267         String persistSysCountry = SystemProperties.get("persist.sys.country", "");
    268         if (!(alwaysPersist || (persistSysLanguage.isEmpty() && persistSysCountry.isEmpty()))) {
    269             Slog.d(LOG_TAG, "getLocaleForLanguageCountry: skipping already persisted");
    270             return null;
    271         }
    272 
    273         // Find the best match we actually have a localization for.
    274         // TODO: this should really follow the CLDR chain of parent locales!
    275         final Locale target = new Locale(language, country);
    276         try {
    277             String[] localeArray = context.getAssets().getLocales();
    278             List<String> locales = new ArrayList<>(Arrays.asList(localeArray));
    279 
    280             // Even in developer mode, you don't want the pseudolocales.
    281             locales.remove("ar-XB");
    282             locales.remove("en-XA");
    283 
    284             Locale firstMatch = null;
    285             for (String locale : locales) {
    286                 final Locale l = Locale.forLanguageTag(locale.replace('_', '-'));
    287 
    288                 // Only consider locales with both language and country.
    289                 if (l == null || "und".equals(l.getLanguage()) ||
    290                         l.getLanguage().isEmpty() || l.getCountry().isEmpty()) {
    291                     continue;
    292                 }
    293                 if (l.getLanguage().equals(target.getLanguage())) {
    294                     // If we got a perfect match, we're done.
    295                     if (l.getCountry().equals(target.getCountry())) {
    296                         Slog.d(LOG_TAG, "getLocaleForLanguageCountry: got perfect match: " +
    297                                l.toLanguageTag());
    298                         return l;
    299                     }
    300                     // Otherwise somewhat arbitrarily take the first locale for the language,
    301                     // unless we get a perfect match later. Note that these come back in no
    302                     // particular order, so there's no reason to think the first match is
    303                     // a particularly good match.
    304                     if (firstMatch == null) {
    305                         firstMatch = l;
    306                     }
    307                 }
    308             }
    309 
    310             // We didn't find the exact locale, so return whichever locale we saw first where
    311             // the language matched (if any).
    312             if (firstMatch != null) {
    313                 Slog.d(LOG_TAG, "getLocaleForLanguageCountry: got a language-only match: " +
    314                        firstMatch.toLanguageTag());
    315                 return firstMatch;
    316             } else {
    317                 Slog.d(LOG_TAG, "getLocaleForLanguageCountry: no locales for language " +
    318                        language);
    319             }
    320         } catch (Exception e) {
    321             Slog.d(LOG_TAG, "getLocaleForLanguageCountry: exception", e);
    322         }
    323 
    324         return null;
    325     }
    326 
    327     /**
    328      * Utility code to set the system locale if it's not set already
    329      * @param context Context to act on.
    330      * @param language Two character language code desired
    331      * @param country Two character country code desired
    332      *
    333      *  {@hide}
    334      */
    335     public static void setSystemLocale(Context context, String language, String country) {
    336         Locale locale = getLocaleForLanguageCountry(context, language, country);
    337         if (locale != null) {
    338             Configuration config = new Configuration();
    339             config.setLocale(locale);
    340             config.userSetLocale = false;
    341             Slog.d(LOG_TAG, "setSystemLocale: updateLocale config=" + config);
    342             try {
    343                 ActivityManagerNative.getDefault().updateConfiguration(config);
    344             } catch (RemoteException e) {
    345                 Slog.d(LOG_TAG, "setSystemLocale exception", e);
    346             }
    347         } else {
    348             Slog.d(LOG_TAG, "setSystemLocale: no locale");
    349         }
    350     }
    351 
    352     /**
    353      * If the timezone is not already set, set it based on the MCC of the SIM.
    354      * @param context Context to act on.
    355      * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
    356      */
    357     private static void setTimezoneFromMccIfNeeded(Context context, int mcc) {
    358         String timezone = SystemProperties.get(ServiceStateTracker.TIMEZONE_PROPERTY);
    359         if (timezone == null || timezone.length() == 0) {
    360             String zoneId = defaultTimeZoneForMcc(mcc);
    361             if (zoneId != null && zoneId.length() > 0) {
    362                 // Set time zone based on MCC
    363                 AlarmManager alarm =
    364                         (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    365                 alarm.setTimeZone(zoneId);
    366                 Slog.d(LOG_TAG, "timezone set to "+zoneId);
    367             }
    368         }
    369     }
    370 
    371     /**
    372      * Get Locale based on the MCC of the SIM.
    373      * @param context Context to act on.
    374      * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
    375      *
    376      * @return locale for the mcc or null if none
    377      */
    378     private static Locale getLocaleFromMcc(Context context, int mcc) {
    379         String language = MccTable.defaultLanguageForMcc(mcc);
    380         String country = MccTable.countryCodeForMcc(mcc);
    381 
    382         Slog.d(LOG_TAG, "getLocaleFromMcc to " + language + "_" + country + " mcc=" + mcc);
    383         return getLocaleForLanguageCountry(context, language, country);
    384     }
    385 
    386     /**
    387      * Set the country code for wifi.  This sets allowed wifi channels based on the
    388      * country of the carrier we see.  If we can't see any, reset to 0 so we don't
    389      * broadcast on forbidden channels.
    390      * @param context Context to act on.
    391      * @param mcc Mobile Country Code of the operator.  0 if not known
    392      */
    393     private static void setWifiCountryCodeFromMcc(Context context, int mcc) {
    394         String country = MccTable.countryCodeForMcc(mcc);
    395         Slog.d(LOG_TAG, "WIFI_COUNTRY_CODE set to " + country);
    396         WifiManager wM = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    397         //persist
    398         wM.setCountryCode(country, true);
    399     }
    400 
    401     static {
    402         sTable = new ArrayList<MccEntry>(240);
    403 
    404 
    405         /*
    406          * The table below is built from two resources:
    407          *
    408          * 1) ITU "Mobile Network Code (MNC) for the international
    409          *   identification plan for mobile terminals and mobile users"
    410          *   which is available as an annex to the ITU operational bulletin
    411          *   available here: http://www.itu.int/itu-t/bulletin/annex.html
    412          *
    413          * 2) The ISO 3166 country codes list, available here:
    414          *    http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html
    415          *
    416          * This table has not been verified.
    417          *
    418          */
    419 
    420 		sTable.add(new MccEntry(202,"gr",2));	//Greece
    421 		sTable.add(new MccEntry(204,"nl",2,"nl"));	//Netherlands (Kingdom of the)
    422 		sTable.add(new MccEntry(206,"be",2));	//Belgium
    423 		sTable.add(new MccEntry(208,"fr",2,"fr"));	//France
    424 		sTable.add(new MccEntry(212,"mc",2));	//Monaco (Principality of)
    425 		sTable.add(new MccEntry(213,"ad",2));	//Andorra (Principality of)
    426 		sTable.add(new MccEntry(214,"es",2,"es"));	//Spain
    427 		sTable.add(new MccEntry(216,"hu",2,"hu"));	//Hungary (Republic of)
    428 		sTable.add(new MccEntry(218,"ba",2));	//Bosnia and Herzegovina
    429 		sTable.add(new MccEntry(219,"hr",2,"hr"));	//Croatia (Republic of)
    430 		sTable.add(new MccEntry(220,"rs",2));	//Serbia and Montenegro
    431 		sTable.add(new MccEntry(222,"it",2,"it"));	//Italy
    432 		sTable.add(new MccEntry(225,"va",2,"it"));	//Vatican City State
    433 		sTable.add(new MccEntry(226,"ro",2));	//Romania
    434 		sTable.add(new MccEntry(228,"ch",2,"de"));	//Switzerland (Confederation of)
    435 		sTable.add(new MccEntry(230,"cz",2,"cs"));	//Czech Republic
    436 		sTable.add(new MccEntry(231,"sk",2));	//Slovak Republic
    437 		sTable.add(new MccEntry(232,"at",2,"de"));	//Austria
    438 		sTable.add(new MccEntry(234,"gb",2,"en"));	//United Kingdom of Great Britain and Northern Ireland
    439 		sTable.add(new MccEntry(235,"gb",2,"en"));	//United Kingdom of Great Britain and Northern Ireland
    440 		sTable.add(new MccEntry(238,"dk",2));	//Denmark
    441 		sTable.add(new MccEntry(240,"se",2,"sv"));	//Sweden
    442 		sTable.add(new MccEntry(242,"no",2));	//Norway
    443 		sTable.add(new MccEntry(244,"fi",2));	//Finland
    444 		sTable.add(new MccEntry(246,"lt",2));	//Lithuania (Republic of)
    445 		sTable.add(new MccEntry(247,"lv",2));	//Latvia (Republic of)
    446 		sTable.add(new MccEntry(248,"ee",2));	//Estonia (Republic of)
    447 		sTable.add(new MccEntry(250,"ru",2));	//Russian Federation
    448 		sTable.add(new MccEntry(255,"ua",2));	//Ukraine
    449 		sTable.add(new MccEntry(257,"by",2));	//Belarus (Republic of)
    450 		sTable.add(new MccEntry(259,"md",2));	//Moldova (Republic of)
    451 		sTable.add(new MccEntry(260,"pl",2));	//Poland (Republic of)
    452 		sTable.add(new MccEntry(262,"de",2,"de"));	//Germany (Federal Republic of)
    453 		sTable.add(new MccEntry(266,"gi",2));	//Gibraltar
    454 		sTable.add(new MccEntry(268,"pt",2));	//Portugal
    455 		sTable.add(new MccEntry(270,"lu",2));	//Luxembourg
    456 		sTable.add(new MccEntry(272,"ie",2,"en"));	//Ireland
    457 		sTable.add(new MccEntry(274,"is",2));	//Iceland
    458 		sTable.add(new MccEntry(276,"al",2));	//Albania (Republic of)
    459 		sTable.add(new MccEntry(278,"mt",2));	//Malta
    460 		sTable.add(new MccEntry(280,"cy",2));	//Cyprus (Republic of)
    461 		sTable.add(new MccEntry(282,"ge",2));	//Georgia
    462 		sTable.add(new MccEntry(283,"am",2));	//Armenia (Republic of)
    463 		sTable.add(new MccEntry(284,"bg",2));	//Bulgaria (Republic of)
    464 		sTable.add(new MccEntry(286,"tr",2));	//Turkey
    465 		sTable.add(new MccEntry(288,"fo",2));	//Faroe Islands
    466                 sTable.add(new MccEntry(289,"ge",2));    //Abkhazia (Georgia)
    467 		sTable.add(new MccEntry(290,"gl",2));	//Greenland (Denmark)
    468 		sTable.add(new MccEntry(292,"sm",2));	//San Marino (Republic of)
    469 		sTable.add(new MccEntry(293,"si",2));	//Slovenia (Republic of)
    470                 sTable.add(new MccEntry(294,"mk",2));   //The Former Yugoslav Republic of Macedonia
    471 		sTable.add(new MccEntry(295,"li",2));	//Liechtenstein (Principality of)
    472                 sTable.add(new MccEntry(297,"me",2));    //Montenegro (Republic of)
    473 		sTable.add(new MccEntry(302,"ca",3,"en"));	//Canada
    474 		sTable.add(new MccEntry(308,"pm",2));	//Saint Pierre and Miquelon (Collectivit territoriale de la Rpublique franaise)
    475 		sTable.add(new MccEntry(310,"us",3,"en"));	//United States of America
    476 		sTable.add(new MccEntry(311,"us",3,"en"));	//United States of America
    477 		sTable.add(new MccEntry(312,"us",3,"en"));	//United States of America
    478 		sTable.add(new MccEntry(313,"us",3,"en"));	//United States of America
    479 		sTable.add(new MccEntry(314,"us",3,"en"));	//United States of America
    480 		sTable.add(new MccEntry(315,"us",3,"en"));	//United States of America
    481 		sTable.add(new MccEntry(316,"us",3,"en"));	//United States of America
    482 		sTable.add(new MccEntry(330,"pr",2));	//Puerto Rico
    483 		sTable.add(new MccEntry(332,"vi",2));	//United States Virgin Islands
    484 		sTable.add(new MccEntry(334,"mx",3));	//Mexico
    485 		sTable.add(new MccEntry(338,"jm",3));	//Jamaica
    486 		sTable.add(new MccEntry(340,"gp",2));	//Guadeloupe (French Department of)
    487 		sTable.add(new MccEntry(342,"bb",3));	//Barbados
    488 		sTable.add(new MccEntry(344,"ag",3));	//Antigua and Barbuda
    489 		sTable.add(new MccEntry(346,"ky",3));	//Cayman Islands
    490 		sTable.add(new MccEntry(348,"vg",3));	//British Virgin Islands
    491 		sTable.add(new MccEntry(350,"bm",2));	//Bermuda
    492 		sTable.add(new MccEntry(352,"gd",2));	//Grenada
    493 		sTable.add(new MccEntry(354,"ms",2));	//Montserrat
    494 		sTable.add(new MccEntry(356,"kn",2));	//Saint Kitts and Nevis
    495 		sTable.add(new MccEntry(358,"lc",2));	//Saint Lucia
    496 		sTable.add(new MccEntry(360,"vc",2));	//Saint Vincent and the Grenadines
    497 		sTable.add(new MccEntry(362,"ai",2));	//Netherlands Antilles
    498 		sTable.add(new MccEntry(363,"aw",2));	//Aruba
    499 		sTable.add(new MccEntry(364,"bs",2));	//Bahamas (Commonwealth of the)
    500 		sTable.add(new MccEntry(365,"ai",3));	//Anguilla
    501 		sTable.add(new MccEntry(366,"dm",2));	//Dominica (Commonwealth of)
    502 		sTable.add(new MccEntry(368,"cu",2));	//Cuba
    503 		sTable.add(new MccEntry(370,"do",2));	//Dominican Republic
    504 		sTable.add(new MccEntry(372,"ht",2));	//Haiti (Republic of)
    505 		sTable.add(new MccEntry(374,"tt",2));	//Trinidad and Tobago
    506 		sTable.add(new MccEntry(376,"tc",2));	//Turks and Caicos Islands
    507 		sTable.add(new MccEntry(400,"az",2));	//Azerbaijani Republic
    508 		sTable.add(new MccEntry(401,"kz",2));	//Kazakhstan (Republic of)
    509 		sTable.add(new MccEntry(402,"bt",2));	//Bhutan (Kingdom of)
    510 		sTable.add(new MccEntry(404,"in",2));	//India (Republic of)
    511 		sTable.add(new MccEntry(405,"in",2));	//India (Republic of)
    512 		sTable.add(new MccEntry(410,"pk",2));	//Pakistan (Islamic Republic of)
    513 		sTable.add(new MccEntry(412,"af",2));	//Afghanistan
    514 		sTable.add(new MccEntry(413,"lk",2));	//Sri Lanka (Democratic Socialist Republic of)
    515 		sTable.add(new MccEntry(414,"mm",2));	//Myanmar (Union of)
    516 		sTable.add(new MccEntry(415,"lb",2));	//Lebanon
    517 		sTable.add(new MccEntry(416,"jo",2));	//Jordan (Hashemite Kingdom of)
    518 		sTable.add(new MccEntry(417,"sy",2));	//Syrian Arab Republic
    519 		sTable.add(new MccEntry(418,"iq",2));	//Iraq (Republic of)
    520 		sTable.add(new MccEntry(419,"kw",2));	//Kuwait (State of)
    521 		sTable.add(new MccEntry(420,"sa",2));	//Saudi Arabia (Kingdom of)
    522 		sTable.add(new MccEntry(421,"ye",2));	//Yemen (Republic of)
    523 		sTable.add(new MccEntry(422,"om",2));	//Oman (Sultanate of)
    524                 sTable.add(new MccEntry(423,"ps",2));    //Palestine
    525 		sTable.add(new MccEntry(424,"ae",2));	//United Arab Emirates
    526 		sTable.add(new MccEntry(425,"il",2));	//Israel (State of)
    527 		sTable.add(new MccEntry(426,"bh",2));	//Bahrain (Kingdom of)
    528 		sTable.add(new MccEntry(427,"qa",2));	//Qatar (State of)
    529 		sTable.add(new MccEntry(428,"mn",2));	//Mongolia
    530 		sTable.add(new MccEntry(429,"np",2));	//Nepal
    531 		sTable.add(new MccEntry(430,"ae",2));	//United Arab Emirates
    532 		sTable.add(new MccEntry(431,"ae",2));	//United Arab Emirates
    533 		sTable.add(new MccEntry(432,"ir",2));	//Iran (Islamic Republic of)
    534 		sTable.add(new MccEntry(434,"uz",2));	//Uzbekistan (Republic of)
    535 		sTable.add(new MccEntry(436,"tj",2));	//Tajikistan (Republic of)
    536 		sTable.add(new MccEntry(437,"kg",2));	//Kyrgyz Republic
    537 		sTable.add(new MccEntry(438,"tm",2));	//Turkmenistan
    538 		sTable.add(new MccEntry(440,"jp",2,"ja"));	//Japan
    539 		sTable.add(new MccEntry(441,"jp",2,"ja"));	//Japan
    540 		sTable.add(new MccEntry(450,"kr",2,"ko"));	//Korea (Republic of)
    541 		sTable.add(new MccEntry(452,"vn",2));	//Viet Nam (Socialist Republic of)
    542 		sTable.add(new MccEntry(454,"hk",2));	//"Hong Kong, China"
    543 		sTable.add(new MccEntry(455,"mo",2));	//"Macao, China"
    544 		sTable.add(new MccEntry(456,"kh",2));	//Cambodia (Kingdom of)
    545 		sTable.add(new MccEntry(457,"la",2));	//Lao People's Democratic Republic
    546 		sTable.add(new MccEntry(460,"cn",2,"zh"));	//China (People's Republic of)
    547 		sTable.add(new MccEntry(461,"cn",2,"zh"));	//China (People's Republic of)
    548 		sTable.add(new MccEntry(466,"tw",2));	//"Taiwan, China"
    549 		sTable.add(new MccEntry(467,"kp",2));	//Democratic People's Republic of Korea
    550 		sTable.add(new MccEntry(470,"bd",2));	//Bangladesh (People's Republic of)
    551 		sTable.add(new MccEntry(472,"mv",2));	//Maldives (Republic of)
    552 		sTable.add(new MccEntry(502,"my",2));	//Malaysia
    553 		sTable.add(new MccEntry(505,"au",2,"en"));	//Australia
    554 		sTable.add(new MccEntry(510,"id",2));	//Indonesia (Republic of)
    555 		sTable.add(new MccEntry(514,"tl",2));	//Democratic Republic of Timor-Leste
    556 		sTable.add(new MccEntry(515,"ph",2));	//Philippines (Republic of the)
    557 		sTable.add(new MccEntry(520,"th",2));	//Thailand
    558 		sTable.add(new MccEntry(525,"sg",2,"en"));	//Singapore (Republic of)
    559 		sTable.add(new MccEntry(528,"bn",2));	//Brunei Darussalam
    560 		sTable.add(new MccEntry(530,"nz",2, "en"));	//New Zealand
    561 		sTable.add(new MccEntry(534,"mp",2));	//Northern Mariana Islands (Commonwealth of the)
    562 		sTable.add(new MccEntry(535,"gu",2));	//Guam
    563 		sTable.add(new MccEntry(536,"nr",2));	//Nauru (Republic of)
    564 		sTable.add(new MccEntry(537,"pg",2));	//Papua New Guinea
    565 		sTable.add(new MccEntry(539,"to",2));	//Tonga (Kingdom of)
    566 		sTable.add(new MccEntry(540,"sb",2));	//Solomon Islands
    567 		sTable.add(new MccEntry(541,"vu",2));	//Vanuatu (Republic of)
    568 		sTable.add(new MccEntry(542,"fj",2));	//Fiji (Republic of)
    569 		sTable.add(new MccEntry(543,"wf",2));	//Wallis and Futuna (Territoire franais d'outre-mer)
    570 		sTable.add(new MccEntry(544,"as",2));	//American Samoa
    571 		sTable.add(new MccEntry(545,"ki",2));	//Kiribati (Republic of)
    572 		sTable.add(new MccEntry(546,"nc",2));	//New Caledonia (Territoire franais d'outre-mer)
    573 		sTable.add(new MccEntry(547,"pf",2));	//French Polynesia (Territoire franais d'outre-mer)
    574 		sTable.add(new MccEntry(548,"ck",2));	//Cook Islands
    575 		sTable.add(new MccEntry(549,"ws",2));	//Samoa (Independent State of)
    576 		sTable.add(new MccEntry(550,"fm",2));	//Micronesia (Federated States of)
    577 		sTable.add(new MccEntry(551,"mh",2));	//Marshall Islands (Republic of the)
    578 		sTable.add(new MccEntry(552,"pw",2));	//Palau (Republic of)
    579 		sTable.add(new MccEntry(602,"eg",2));	//Egypt (Arab Republic of)
    580 		sTable.add(new MccEntry(603,"dz",2));	//Algeria (People's Democratic Republic of)
    581 		sTable.add(new MccEntry(604,"ma",2));	//Morocco (Kingdom of)
    582 		sTable.add(new MccEntry(605,"tn",2));	//Tunisia
    583 		sTable.add(new MccEntry(606,"ly",2));	//Libya (Socialist People's Libyan Arab Jamahiriya)
    584 		sTable.add(new MccEntry(607,"gm",2));	//Gambia (Republic of the)
    585 		sTable.add(new MccEntry(608,"sn",2));	//Senegal (Republic of)
    586 		sTable.add(new MccEntry(609,"mr",2));	//Mauritania (Islamic Republic of)
    587 		sTable.add(new MccEntry(610,"ml",2));	//Mali (Republic of)
    588 		sTable.add(new MccEntry(611,"gn",2));	//Guinea (Republic of)
    589 		sTable.add(new MccEntry(612,"ci",2));	//Cte d'Ivoire (Republic of)
    590 		sTable.add(new MccEntry(613,"bf",2));	//Burkina Faso
    591 		sTable.add(new MccEntry(614,"ne",2));	//Niger (Republic of the)
    592 		sTable.add(new MccEntry(615,"tg",2));	//Togolese Republic
    593 		sTable.add(new MccEntry(616,"bj",2));	//Benin (Republic of)
    594 		sTable.add(new MccEntry(617,"mu",2));	//Mauritius (Republic of)
    595 		sTable.add(new MccEntry(618,"lr",2));	//Liberia (Republic of)
    596 		sTable.add(new MccEntry(619,"sl",2));	//Sierra Leone
    597 		sTable.add(new MccEntry(620,"gh",2));	//Ghana
    598 		sTable.add(new MccEntry(621,"ng",2));	//Nigeria (Federal Republic of)
    599 		sTable.add(new MccEntry(622,"td",2));	//Chad (Republic of)
    600 		sTable.add(new MccEntry(623,"cf",2));	//Central African Republic
    601 		sTable.add(new MccEntry(624,"cm",2));	//Cameroon (Republic of)
    602 		sTable.add(new MccEntry(625,"cv",2));	//Cape Verde (Republic of)
    603 		sTable.add(new MccEntry(626,"st",2));	//Sao Tome and Principe (Democratic Republic of)
    604 		sTable.add(new MccEntry(627,"gq",2));	//Equatorial Guinea (Republic of)
    605 		sTable.add(new MccEntry(628,"ga",2));	//Gabonese Republic
    606 		sTable.add(new MccEntry(629,"cg",2));	//Congo (Republic of the)
    607 		sTable.add(new MccEntry(630,"cg",2));	//Democratic Republic of the Congo
    608 		sTable.add(new MccEntry(631,"ao",2));	//Angola (Republic of)
    609 		sTable.add(new MccEntry(632,"gw",2));	//Guinea-Bissau (Republic of)
    610 		sTable.add(new MccEntry(633,"sc",2));	//Seychelles (Republic of)
    611 		sTable.add(new MccEntry(634,"sd",2));	//Sudan (Republic of the)
    612 		sTable.add(new MccEntry(635,"rw",2));	//Rwanda (Republic of)
    613 		sTable.add(new MccEntry(636,"et",2));	//Ethiopia (Federal Democratic Republic of)
    614 		sTable.add(new MccEntry(637,"so",2));	//Somali Democratic Republic
    615 		sTable.add(new MccEntry(638,"dj",2));	//Djibouti (Republic of)
    616 		sTable.add(new MccEntry(639,"ke",2));	//Kenya (Republic of)
    617 		sTable.add(new MccEntry(640,"tz",2));	//Tanzania (United Republic of)
    618 		sTable.add(new MccEntry(641,"ug",2));	//Uganda (Republic of)
    619 		sTable.add(new MccEntry(642,"bi",2));	//Burundi (Republic of)
    620 		sTable.add(new MccEntry(643,"mz",2));	//Mozambique (Republic of)
    621 		sTable.add(new MccEntry(645,"zm",2));	//Zambia (Republic of)
    622 		sTable.add(new MccEntry(646,"mg",2));	//Madagascar (Republic of)
    623 		sTable.add(new MccEntry(647,"re",2));	//Reunion (French Department of)
    624 		sTable.add(new MccEntry(648,"zw",2));	//Zimbabwe (Republic of)
    625 		sTable.add(new MccEntry(649,"na",2));	//Namibia (Republic of)
    626 		sTable.add(new MccEntry(650,"mw",2));	//Malawi
    627 		sTable.add(new MccEntry(651,"ls",2));	//Lesotho (Kingdom of)
    628 		sTable.add(new MccEntry(652,"bw",2));	//Botswana (Republic of)
    629 		sTable.add(new MccEntry(653,"sz",2));	//Swaziland (Kingdom of)
    630 		sTable.add(new MccEntry(654,"km",2));	//Comoros (Union of the)
    631 		sTable.add(new MccEntry(655,"za",2,"en"));	//South Africa (Republic of)
    632 		sTable.add(new MccEntry(657,"er",2));	//Eritrea
    633 		sTable.add(new MccEntry(702,"bz",2));	//Belize
    634 		sTable.add(new MccEntry(704,"gt",2));	//Guatemala (Republic of)
    635 		sTable.add(new MccEntry(706,"sv",2));	//El Salvador (Republic of)
    636 		sTable.add(new MccEntry(708,"hn",3));	//Honduras (Republic of)
    637 		sTable.add(new MccEntry(710,"ni",2));	//Nicaragua
    638 		sTable.add(new MccEntry(712,"cr",2));	//Costa Rica
    639 		sTable.add(new MccEntry(714,"pa",2));	//Panama (Republic of)
    640 		sTable.add(new MccEntry(716,"pe",2));	//Peru
    641 		sTable.add(new MccEntry(722,"ar",3));	//Argentine Republic
    642 		sTable.add(new MccEntry(724,"br",2));	//Brazil (Federative Republic of)
    643 		sTable.add(new MccEntry(730,"cl",2));	//Chile
    644 		sTable.add(new MccEntry(732,"co",3));	//Colombia (Republic of)
    645 		sTable.add(new MccEntry(734,"ve",2));	//Venezuela (Bolivarian Republic of)
    646 		sTable.add(new MccEntry(736,"bo",2));	//Bolivia (Republic of)
    647 		sTable.add(new MccEntry(738,"gy",2));	//Guyana
    648 		sTable.add(new MccEntry(740,"ec",2));	//Ecuador
    649 		sTable.add(new MccEntry(742,"gf",2));	//French Guiana (French Department of)
    650 		sTable.add(new MccEntry(744,"py",2));	//Paraguay (Republic of)
    651 		sTable.add(new MccEntry(746,"sr",2));	//Suriname (Republic of)
    652 		sTable.add(new MccEntry(748,"uy",2));	//Uruguay (Eastern Republic of)
    653 		sTable.add(new MccEntry(750,"fk",2));	//Falkland Islands (Malvinas)
    654         //table.add(new MccEntry(901,"",2));	//"International Mobile, shared code"
    655 
    656         Collections.sort(sTable);
    657     }
    658 }
    659