From 8f33330e42fa169dee69d2d33bac54b701149d5a Mon Sep 17 00:00:00 2001
From: akwizgran <michael@briarproject.org>
Date: Sat, 15 Dec 2012 16:17:04 +0000
Subject: [PATCH] International dialling support for the modem plugin
 (untested).

---
 .../sf/briar/plugins/modem/CountryCodes.java  | 283 ++++++++++++++++++
 .../sf/briar/plugins/modem/ModemPlugin.java   |  34 ++-
 2 files changed, 310 insertions(+), 7 deletions(-)
 create mode 100644 briar-core/src/net/sf/briar/plugins/modem/CountryCodes.java

diff --git a/briar-core/src/net/sf/briar/plugins/modem/CountryCodes.java b/briar-core/src/net/sf/briar/plugins/modem/CountryCodes.java
new file mode 100644
index 0000000000..1029a1f93b
--- /dev/null
+++ b/briar-core/src/net/sf/briar/plugins/modem/CountryCodes.java
@@ -0,0 +1,283 @@
+package net.sf.briar.plugins.modem;
+
+import java.util.HashMap;
+import java.util.Map;
+
+class CountryCodes {
+
+	private static final Country[] COUNTRIES = {
+		new Country("AD", "Andorra", "376", "00", ""),
+		new Country("AE", "United Arab Emirates", "971", "00", "0"),
+		new Country("AF", "Afghanistan", "93", "00", "0"),
+		new Country("AG", "Antigua and Barbuda", "1", "011", "1"),
+		new Country("AI", "Anguilla", "1", "011", "1"),
+		new Country("AL", "Albania", "355", "00", "0"),
+		new Country("AM", "Armenia", "374", "00", "8"),
+		new Country("AN", "Netherlands Antilles", "599", "00", "0"),
+		new Country("AO", "Angola", "244", "00", "0"),
+		new Country("AQ", "Antarctica", "672", "", ""),
+		new Country("AR", "Argentina", "54", "00", "0"),
+		new Country("AS", "American Samoa", "1", "011", "1"),
+		new Country("AT", "Austria", "43", "00", "0"),
+		new Country("AU", "Australia", "61", "00", ""),
+		new Country("AW", "Aruba", "297", "00", ""),
+		new Country("AZ", "Azerbaijan", "994", "00", "8"),
+		new Country("BA", "Bosnia and Herzegovina", "387", "00", "0"),
+		new Country("BB", "Barbados", "1", "011", "1"),
+		new Country("BD", "Bangladesh", "880", "00", "0"),
+		new Country("BE", "Belgium", "32", "00", "0"),
+		new Country("BF", "Burkina Faso", "226", "00", ""),
+		new Country("BG", "Bulgaria", "359", "00", "0"),
+		new Country("BH", "Bahrain", "973", "00", ""),
+		new Country("BI", "Burundi", "257", "00", ""),
+		new Country("BJ", "Benin", "229", "00", ""),
+		new Country("BM", "Bermuda", "1", "011", "1"),
+		new Country("BN", "Brunei Darussalam", "673", "00", "0"),
+		new Country("BO", "Bolivia", "591", "00", "0"),
+		new Country("BR", "Brazil", "55", "00", "0"),
+		new Country("BS", "Bahamas", "1", "011", "1"),
+		new Country("BT", "Bhutan", "975", "00", ""),
+		new Country("BV", "Bouvet Island (Norway)", "47", "00", ""),
+		new Country("BW", "Botswana", "267", "00", ""),
+		new Country("BY", "Belarus", "375", "8**10", "8"),
+		new Country("BZ", "Belize", "501", "00", "0"),
+		new Country("CA", "Canada", "1", "011", "1"),
+		new Country("CC", "Cocos (Keeling) Islands", "61", "0011", "0"),
+		new Country("CD", "Congo", "243", "00", ""),
+		new Country("CF", "Central African Republic", "236", "00", ""),
+		new Country("CG", "Congo", "242", "00", ""),
+		new Country("CH", "Switzerland", "41", "00", "0"),
+		new Country("CI", "Cote D'Ivoire", "225", "00", "0"),
+		new Country("CK", "Cook Islands", "682", "00", "00"),
+		new Country("CL", "Chile", "56", "00", "0"),
+		new Country("CM", "Cameroon", "237", "00", ""),
+		new Country("CN", "China", "86", "00", "0"),
+		new Country("CO", "Colombia", "57", "009", "09"),
+		new Country("CR", "Costa Rica", "506", "00", ""),
+		new Country("CU", "Cuba", "53", "119", "0"),
+		new Country("CV", "Cape Verde Islands", "238", "0", ""),
+		new Country("CX", "Christmas Island", "61", "0011", "0"),
+		new Country("CY", "Cyprus", "357", "00", ""),
+		new Country("CZ", "Czech Republic", "420", "00", ""),
+		new Country("DE", "Germany", "49", "00", "0"),
+		new Country("DJ", "Djibouti", "253", "00", ""),
+		new Country("DK", "Denmark", "45", "00", ""),
+		new Country("DM", "Dominica", "1", "011", "1"),
+		new Country("DO", "Dominican Republic", "1", "011", "1"),
+		new Country("DZ", "Algeria", "213", "00", "7"),
+		new Country("EC", "Ecuador", "593", "00", "0"),
+		new Country("EE", "Estonia", "372", "00", ""),
+		new Country("EG", "Egypt", "20", "00", "0"),
+		new Country("EH", "Western Sahara", "212", "00", "0"),
+		new Country("ER", "Eritrea", "291", "00", "0"),
+		new Country("ES", "Spain", "34", "00", ""),
+		new Country("ET", "Ethiopia", "251", "00", "0"),
+		new Country("FI", "Finland", "358", "00", "0"),
+		new Country("FJ", "Fiji", "679", "00", ""),
+		new Country("FK", "Falkland Islands (Malvinas)", "500", "00", ""),
+		new Country("FM", "Micronesia", "691", "011", "1"),
+		new Country("FO", "Faroe Islands", "298", "00", ""),
+		new Country("FR", "France", "33", "00", ""),
+		new Country("GA", "Gabonese Republic", "241", "00", ""),
+		new Country("GB", "United Kingdom", "44", "00", "0"),
+		new Country("GD", "Grenada", "1", "011", "4"),
+		new Country("GE", "Georgia", "995", "8**10", "8"),
+		new Country("GF", "French Guiana", "594", "00", ""),
+		new Country("GH", "Ghana", "233", "00", ""),
+		new Country("GI", "Gibraltar", "350", "00", ""),
+		new Country("GL", "Greenland", "299", "00", ""),
+		new Country("GM", "Gambia", "220", "00", ""),
+		new Country("GN", "Guinea", "224", "00", "0"),
+		new Country("GP", "Guadeloupe", "590", "00", ""),
+		new Country("GQ", "Equatorial Guinea", "240", "00", ""),
+		new Country("GR", "Greece", "30", "00", ""),
+		new Country("GS", "South Georgia and the South Sandwich Islands", "995", "8**10", "8"),
+		new Country("GT", "Guatemala", "502", "00", ""),
+		new Country("GU", "Guam", "1", "011", "1"),
+		new Country("GW", "Guinea-Bissau", "245", "00", ""),
+		new Country("GY", "Guyana", "592", "001", "0"),
+		new Country("HK", "Hong Kong", "852", "001", ""),
+		new Country("HM", "Heard Island and McDonald Islands", "692", "00", "0"),
+		new Country("HN", "Honduras", "504", "00", "0"),
+		new Country("HR", "Croatia", "385", "00", "0"),
+		new Country("HT", "Haiti", "509", "00", "0"),
+		new Country("HU", "Hungary", "36", "00", "06"),
+		new Country("ID", "Indonesia", "62", "001", "0"),
+		new Country("IE", "Ireland", "353", "00", "0"),
+		new Country("IL", "Israel", "972", "00", "0"),
+		new Country("IN", "India", "91", "00", "0"),
+		new Country("IO", "British Indian Ocean Territory", "246", "00", ""),
+		new Country("IQ", "Iraq", "964", "00", "0"),
+		new Country("IR", "Iran", "98", "00", "0"),
+		new Country("IS", "Iceland", "354", "00", "0"),
+		new Country("IT", "Italy", "39", "00", ""),
+		new Country("JM", "Jamaica", "1", "011", "1"),
+		new Country("JO", "Jordan", "962", "00", "0"),
+		new Country("JP", "Japan", "81", "001", "0"),
+		new Country("KE", "Kenya", "254", "000", "0"),
+		new Country("KG", "Kyrgyzstan", "996", "00", "0"),
+		new Country("KH", "Cambodia", "855", "001", "0"),
+		new Country("KI", "Kiribati", "686", "00", "0"),
+		new Country("KM", "Comoros", "269", "00", ""),
+		new Country("KN", "Saint Kitts and Nevis", "1", "011", "1"),
+		new Country("KP", "Korea (North)", "850", "00", "0"),
+		new Country("KR", "Korea (South)", "82", "001", "0"),
+		new Country("KW", "Kuwait", "965", "00", "0"),
+		new Country("KY", "Cayman Islands", "1", "011", "1"),
+		new Country("KZ", "Kazakhstan", "7", "8**10", "8"),
+		new Country("LA", "Laos", "856", "00", "0"),
+		new Country("LB", "Lebanon", "961", "00", "0"),
+		new Country("LC", "Saint Lucia", "1", "011", "1"),
+		new Country("LI", "Liechtenstein", "423", "00", ""),
+		new Country("LK", "Sri Lanka", "94", "00", "0"),
+		new Country("LR", "Liberia", "231", "00", "22"),
+		new Country("LS", "Lesotho", "266", "00", "0"),
+		new Country("LT", "Lithuania", "370", "00", "8"),
+		new Country("LU", "Luxembourg", "352", "00", ""),
+		new Country("LV", "Latvia", "371", "00", "8"),
+		new Country("LY", "Libya", "218", "00", "0"),
+		new Country("MA", "Morocco", "212", "00", ""),
+		new Country("MC", "Monaco", "377", "00", "0"),
+		new Country("MD", "Moldova", "373", "00", "0"),
+		new Country("ME", "Montenegro", "382", "99", "0"),
+		new Country("MG", "Madagascar", "261", "00", "0"),
+		new Country("MH", "Marshall Islands", "692", "011", "1"),
+		new Country("MK", "Macedonia", "389", "00", "0"),
+		new Country("ML", "Mali", "223", "00", "0"),
+		new Country("MM", "Myanmar", "95", "00", ""),
+		new Country("MN", "Mongolia", "976", "001", "0"),
+		new Country("MO", "Macao", "853", "00", "0"),
+		new Country("MP", "Northern Mariana Islands", "1", "011", "1"),
+		new Country("MQ", "Martinique", "596", "00", "0"),
+		new Country("MR", "Mauritania", "222", "00", "0"),
+		new Country("MS", "Montserrat", "1", "011", "1"),
+		new Country("MT", "Malta", "356", "00", "21"),
+		new Country("MU", "Mauritius", "230", "00", "0"),
+		new Country("MV", "Maldives", "960", "00", "0"),
+		new Country("MW", "Malawi", "265", "00", ""),
+		new Country("MX", "Mexico", "52", "00", "01"),
+		new Country("MY", "Malaysia", "60", "00", "0"),
+		new Country("MZ", "Mozambique", "258", "00", "0"),
+		new Country("NA", "Namibia", "264", "00", "0"),
+		new Country("NC", "New Caledonia", "687", "00", "0"),
+		new Country("NE", "Niger", "227", "00", "0"),
+		new Country("NF", "Norfolk Island", "672", "00", ""),
+		new Country("NG", "Nigeria", "234", "009", "0"),
+		new Country("NI", "Nicaragua", "505", "00", "0"),
+		new Country("NL", "Netherlands", "31", "00", "0"),
+		new Country("NO", "Norway", "47", "00", ""),
+		new Country("NP", "Nepal", "977", "00", "0"),
+		new Country("NR", "Nauru", "674", "00", "0"),
+		new Country("NU", "Niue", "683", "00", "0"),
+		new Country("NZ", "New Zealand", "64", "00", "0"),
+		new Country("OM", "Oman", "968", "00", "0"),
+		new Country("PA", "Panama", "507", "00", "0"),
+		new Country("PE", "Peru", "51", "00", "0"),
+		new Country("PF", "French Polynesia", "689", "00", ""),
+		new Country("PG", "Papua New Guinea", "675", "05", ""),
+		new Country("PH", "Philippines", "63", "00", "0"),
+		new Country("PK", "Pakistan", "92", "00", "0"),
+		new Country("PL", "Poland", "48", "00", "0"),
+		new Country("PM", "Saint Pierre and Miquelon", "508", "00", "0"),
+		new Country("PN", "Pitcairn", "872", "", ""),
+		new Country("PR", "Puerto Rico", "1", "011", "1"),
+		new Country("PS", "Palestine", "970", "00", "0"),
+		new Country("PT", "Portugal", "351", "00", ""),
+		new Country("PW", "Palau", "680", "011", ""),
+		new Country("PY", "Paraguay", "595", "002", "0"),
+		new Country("QA", "Qatar", "974", "00", "0"),
+		new Country("RE", "Reunion", "262", "00", "0"),
+		new Country("RO", "Romania", "40", "00", "0"),
+		new Country("RS", "Serbia", "381", "99", "0"),
+		new Country("RU", "Russia", "7", " 8**10", "8"),
+		new Country("RW", "Rwanda", "250", "00", "0"),
+		new Country("SA", "Saudi Arabia", "966", "00", "0"),
+		new Country("SB", "Solomon Islands", "677", "00", ""),
+		new Country("SC", "Seychelles", "248", "00", "0"),
+		new Country("SD", "Sudan", "249", "00", "0"),
+		new Country("SE", "Sweden", "46", "00", "0"),
+		new Country("SG", "Singapore", "65", "001", ""),
+		new Country("SH", "Saint Helena", "290", "00", ""),
+		new Country("SI", "Slovenia", "386", "00", "0"),
+		new Country("SJ", "Svalbard and Jan Mayen", "378", "00", "0"),
+		new Country("SK", "Slovakia", "421", "00", "0"),
+		new Country("SL", "Sierra Leone", "232", "00", "0"),
+		new Country("SM", "San Marino", "378", "00", "0"),
+		new Country("SN", "Senegal", "221", "00", "0"),
+		new Country("SO", "Somalia", "252", "00", ""),
+		new Country("SR", "Suriname", "597", "00", ""),
+		new Country("ST", "Sao Tome and Principe", "239", "00", "0"),
+		new Country("SV", "El Salvador", "503", "00", ""),
+		new Country("SY", "Syria", "963", "00", "0"),
+		new Country("SZ", "Swaziland", "268", "00", ""),
+		new Country("TC", "Turks and Caicos Islands", "1", "011", "1"),
+		new Country("TD", "Chad", "235", "15", ""),
+		new Country("TF", "French Southern Territories", "596", "00", "0"),
+		new Country("TG", "Togo", "228", "00", ""),
+		new Country("TH", "Thailand", "66", "001", "0"),
+		new Country("TJ", "Tajikistan", "992", "8**10", "8"),
+		new Country("TK", "Tokelau", "690", "00", ""),
+		new Country("TL", "Timor-Leste", "670", "00", ""),
+		new Country("TM", "Turkmenistan", "993", "8**10", "8"),
+		new Country("TN", "Tunisia", "216", "00", "0"),
+		new Country("TO", "Tonga Islands", "676", "00", ""),
+		new Country("TR", "Turkey", "90", "00", "0"),
+		new Country("TT", "Trinidad and Tobago", "1", "011", "1"),
+		new Country("TV", "Tuvalu", "688", "00", ""),
+		new Country("TW", "Taiwan", "886", "002", ""),
+		new Country("TZ", "Tanzania", "255", "000", "0"),
+		new Country("UA", "Ukraine", "380", "8**10", "8"),
+		new Country("UG", "Uganda", "256", "000", "0"),
+		new Country("US", "United States", "1", "011", "1"),
+		new Country("UY", "Uruguay", "598", "00", "0"),
+		new Country("UZ", "Uzbekistan", "998", "8**10", "8"),
+		new Country("VA", "Holy See (Vatican City State)", "379", "00", ""),
+		new Country("VC", "Saint Vincent and the Grenadines", "1", "011", "1"),
+		new Country("VE", "Venezuela", "58", "00", "0"),
+		new Country("VG", "Virgin Islands (British)", "1", "011", "1"),
+		new Country("VI", "Virgin Islands (U.S.)", "1", "011", "1"),
+		new Country("VN", "Viet Nam", "84", "00", "0"),
+		new Country("VU", "Vanuatu", "678", "00", ""),
+		new Country("WF", "Wallis and Futuna Islands", "681", "19", ""),
+		new Country("WS", "Samoa (Western)", "685", "0", "0"),
+		new Country("YE", "Yemen", "967", "00", "0"),
+		new Country("YT", "Mayotte", "269", "00", ""),
+		new Country("ZA", "South Africa", "27", "09", "0"),
+		new Country("ZM", "Zambia", "260", "00", "0"),
+		new Country("ZW", "Zimbabwe", "263", "110", "0")
+	};
+
+	private static final Map<String, Country> COUNTRY_MAP =
+			new HashMap<String, Country>();
+
+	static {
+		for(Country c : COUNTRIES) COUNTRY_MAP.put(c.iso3166, c);
+	}
+
+	static String translate(String number, String fromIso, String toIso) {
+		Country from = COUNTRY_MAP.get(fromIso), to = COUNTRY_MAP.get(toIso);
+		if(from == null || to == null) return null;
+		// Strip the IDD prefix and country code from the number if present
+		String iddCountryCode = to.idd + to.countryCode;
+		if(number.startsWith(iddCountryCode))
+			number = number.substring(iddCountryCode.length());
+		// Strip the NDD prefix from the number if present
+		if(number.startsWith(to.ndd))
+			number = number.substring(to.ndd.length());
+		if(from == to) return from.ndd + number;
+		return from.idd + to.countryCode + number;
+	}
+
+	private static class Country {
+
+		private final String iso3166, countryCode, ndd, idd;
+
+		private Country(String iso3166, String englishName, String countryCode,
+				String ndd, String idd) {
+			this.iso3166 = iso3166;
+			this.countryCode = countryCode;
+			this.ndd = ndd;
+			this.idd = idd;
+		}
+	}
+}
\ No newline at end of file
diff --git a/briar-core/src/net/sf/briar/plugins/modem/ModemPlugin.java b/briar-core/src/net/sf/briar/plugins/modem/ModemPlugin.java
index 975b3d5977..269b289116 100644
--- a/briar-core/src/net/sf/briar/plugins/modem/ModemPlugin.java
+++ b/briar-core/src/net/sf/briar/plugins/modem/ModemPlugin.java
@@ -19,7 +19,6 @@ import java.util.logging.Logger;
 
 import jssc.SerialPortList;
 import net.sf.briar.api.ContactId;
-import net.sf.briar.api.TransportConfig;
 import net.sf.briar.api.TransportProperties;
 import net.sf.briar.api.crypto.PseudoRandom;
 import net.sf.briar.api.plugins.PluginExecutor;
@@ -137,6 +136,9 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
 				LOG.info("Previous poll still in progress");
 			return;
 		}
+		// Get the ISO 3166 code for the caller's country
+		String fromIso = callback.getLocalProperties().get("iso3166");
+		if(StringUtils.isNullOrEmpty(fromIso)) return;
 		// Call contacts one at a time in a random order
 		Map<ContactId, TransportProperties> remote =
 				callback.getRemoteProperties();
@@ -145,8 +147,18 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
 		Iterator<ContactId> it = contacts.iterator();
 		while(it.hasNext() && running) {
 			ContactId c = it.next();
-			String number = remote.get(c).get("number");
+			// Get the ISO 3166 code for the callee's country
+			TransportProperties properties = remote.get(c);
+			if(properties == null) continue;
+			String toIso = properties.get("iso3166");
+			if(StringUtils.isNullOrEmpty(toIso)) continue;
+			// Get the callee's phone number
+			String number = properties.get("number");
 			if(StringUtils.isNullOrEmpty(number)) continue;
+			// Convert the number into direct dialling form
+			number = CountryCodes.translate(number, fromIso, toIso);
+			if(number == null) continue;
+			// Dial the number
 			try {
 				if(!modem.dial(number)) continue;
 			} catch(IOException e) {
@@ -171,13 +183,21 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
 
 	public DuplexTransportConnection createConnection(ContactId c) {
 		if(!running) return null;
-		TransportConfig config = callback.getConfig();
-		String fromIso = config.get("iso3166");
+		// Get the ISO 3166 code for the caller's country
+		String fromIso = callback.getLocalProperties().get("iso3166");
 		if(StringUtils.isNullOrEmpty(fromIso)) return null;
-		Map<ContactId, TransportProperties> remote =
-				callback.getRemoteProperties();
-		String number = remote.get(c).get("number");
+		// Get the ISO 3166 code for the callee's country
+		TransportProperties properties = callback.getRemoteProperties().get(c);
+		if(properties == null) return null;
+		String toIso = properties.get("iso3166");
+		if(StringUtils.isNullOrEmpty(toIso)) return null;
+		// Get the callee's phone number
+		String number = properties.get("number");
 		if(StringUtils.isNullOrEmpty(number)) return null;
+		// Convert the number into direct dialling form
+		number = CountryCodes.translate(number, fromIso, toIso);
+		if(number == null) return null;
+		// Dial the number
 		try {
 			if(!modem.dial(number)) return null;
 		} catch(IOException e) {
-- 
GitLab