ofono.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check
@ 2023-12-19 18:36 Denis Kenzior
  2023-12-19 18:36 ` [PATCH v2 02/15] include: Allow multiple context types Denis Kenzior
                   ` (14 more replies)
  0 siblings, 15 replies; 16+ messages in thread
From: Denis Kenzior @ 2023-12-19 18:36 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

---
 acinclude.m4 | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/acinclude.m4 b/acinclude.m4
index 4932ac6b..656888d7 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -23,8 +23,7 @@ AC_DEFUN([AC_PROG_CC_ASAN], [
 ])
 
 AC_DEFUN([AC_PROG_CC_LSAN], [
-	AC_CACHE_CHECK([whether ${CC-cc} accepts -fsanitize=leak], ac_cv_prog_cc
-_lsan, [
+	AC_CACHE_CHECK([whether ${CC-cc} accepts -fsanitize=leak], ac_cv_prog_cc_lsan, [
 		echo 'void f(){}' > conftest.c
 		if test -z "`${CC-cc} -fsanitize=leak -c conftest.c 2>&1`"; then
 			ac_cv_prog_cc_lsan=yes
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 02/15] include: Allow multiple context types
  2023-12-19 18:36 [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
@ 2023-12-19 18:36 ` Denis Kenzior
  2023-12-19 18:37 ` [PATCH v2 03/15] module: Add support for ofono modules Denis Kenzior
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2023-12-19 18:36 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

---
 include/gprs-context.h   | 8 ++++----
 include/gprs-provision.h | 4 +++-
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/include/gprs-context.h b/include/gprs-context.h
index 75958284..81055d89 100644
--- a/include/gprs-context.h
+++ b/include/gprs-context.h
@@ -33,10 +33,10 @@ struct ofono_modem;
 
 enum ofono_gprs_context_type {
 	OFONO_GPRS_CONTEXT_TYPE_ANY = 0,
-	OFONO_GPRS_CONTEXT_TYPE_INTERNET,
-	OFONO_GPRS_CONTEXT_TYPE_MMS,
-	OFONO_GPRS_CONTEXT_TYPE_WAP,
-	OFONO_GPRS_CONTEXT_TYPE_IMS,
+	OFONO_GPRS_CONTEXT_TYPE_INTERNET	= 0x0001,
+	OFONO_GPRS_CONTEXT_TYPE_MMS		= 0x0002,
+	OFONO_GPRS_CONTEXT_TYPE_WAP		= 0x0004,
+	OFONO_GPRS_CONTEXT_TYPE_IMS		= 0x0008,
 };
 
 struct ofono_gprs_primary_context {
diff --git a/include/gprs-provision.h b/include/gprs-provision.h
index 2dd792b5..75808e66 100644
--- a/include/gprs-provision.h
+++ b/include/gprs-provision.h
@@ -26,10 +26,12 @@
 extern "C" {
 #endif
 
+#include <stdint.h>
+
 #include "gprs-context.h"
 
 struct ofono_gprs_provision_data {
-	enum ofono_gprs_context_type type;
+	uint32_t type; /* Multiple types can be set in a bitmap */
 	enum ofono_gprs_proto proto;
 	char *name;
 	char *apn;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 03/15] module: Add support for ofono modules
  2023-12-19 18:36 [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
  2023-12-19 18:36 ` [PATCH v2 02/15] include: Allow multiple context types Denis Kenzior
@ 2023-12-19 18:37 ` Denis Kenzior
  2023-12-19 18:37 ` [PATCH v2 04/15] doc: docs for intermediate provisioning db format Denis Kenzior
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2023-12-19 18:37 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

Modules are meant to replace manually calling various __foo_init
and __foo_cleanup calls in main.c.  Instead a single ofono_modules_init
and ofono_modules_cleanup invocation will initialize / cleanup all
registered ofono modules.
---
 Makefile.am   |  3 ++-
 src/main.c    | 11 ++++-------
 src/manager.c |  6 ++++--
 src/modem.c   |  7 +++++--
 src/module.c  | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/ofono.h   | 22 ++++++++++++++++++---
 6 files changed, 89 insertions(+), 15 deletions(-)
 create mode 100644 src/module.c

diff --git a/Makefile.am b/Makefile.am
index e7fd030f..f7b59a47 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -725,7 +725,8 @@ src_ofonod_SOURCES = $(builtin_sources) $(gatchat_sources) src/ofono.ver \
 			src/handsfree-audio.c src/bluetooth.h \
 			src/hfp.h src/siri.c \
 			src/netmon.c src/lte.c src/ims.c \
-			src/netmonagent.c src/netmonagent.h
+			src/netmonagent.c src/netmonagent.h \
+			src/module.c
 
 src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) $(ell_ldadd) \
 			@GLIB_LIBS@ @DBUS_LIBS@ -ldl
diff --git a/src/main.c b/src/main.c
index 4529cde1..82157700 100644
--- a/src/main.c
+++ b/src/main.c
@@ -274,12 +274,10 @@ int main(int argc, char **argv)
 
 	__ofono_dbus_init(conn);
 
-	__ofono_modemwatch_init();
-
-	__ofono_manager_init();
+	if (__ofono_modules_init() < 0)
+		goto fail_module_init;
 
 	__ofono_plugin_init(option_plugin, option_noplugin);
-
 	g_free(option_plugin);
 	g_free(option_noplugin);
 
@@ -287,10 +285,9 @@ int main(int argc, char **argv)
 
 	__ofono_plugin_cleanup();
 
-	__ofono_manager_cleanup();
-
-	__ofono_modemwatch_cleanup();
+	__ofono_modules_cleanup();
 
+fail_module_init:
 	__ofono_dbus_cleanup();
 	dbus_connection_unref(conn);
 
diff --git a/src/manager.c b/src/manager.c
index 404f2cad..e3307adb 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -95,7 +95,7 @@ static const GDBusSignalTable manager_signals[] = {
 	{ }
 };
 
-int __ofono_manager_init(void)
+static int manager_init(void)
 {
 	DBusConnection *conn = ofono_dbus_get_connection();
 	gboolean ret;
@@ -111,10 +111,12 @@ int __ofono_manager_init(void)
 	return 0;
 }
 
-void __ofono_manager_cleanup(void)
+static void manager_cleanup(void)
 {
 	DBusConnection *conn = ofono_dbus_get_connection();
 
 	g_dbus_unregister_interface(conn, OFONO_MANAGER_PATH,
 					OFONO_MANAGER_INTERFACE);
 }
+
+OFONO_MODULE(manager, manager_init, manager_cleanup)
diff --git a/src/modem.c b/src/modem.c
index 60717717..354d2b86 100644
--- a/src/modem.c
+++ b/src/modem.c
@@ -1918,12 +1918,13 @@ static void sim_watch(struct ofono_atom *atom,
 							modem, NULL);
 }
 
-void __ofono_modemwatch_init(void)
+static int modemwatch_init(void)
 {
 	g_modemwatches = __ofono_watchlist_new(g_free);
+	return 0;
 }
 
-void __ofono_modemwatch_cleanup(void)
+static void modemwatch_cleanup(void)
 {
 	__ofono_watchlist_free(g_modemwatches);
 }
@@ -2319,3 +2320,5 @@ void __ofono_modem_dec_emergency_mode(struct ofono_modem *modem)
 out:
 	modem->emergency--;
 }
+
+OFONO_MODULE(modemwatch, modemwatch_init, modemwatch_cleanup)
diff --git a/src/module.c b/src/module.c
new file mode 100644
index 00000000..273a7183
--- /dev/null
+++ b/src/module.c
@@ -0,0 +1,55 @@
+/*
+ *  oFono - Open Source Telephony
+ *  Copyright (C) 2023  Cruise, LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <ell/ell.h>
+
+#include "ofono.h"
+
+extern struct ofono_module_desc __start___ofono_module[];
+extern struct ofono_module_desc __stop___ofono_module[];
+
+int __ofono_modules_init(void)
+{
+	struct ofono_module_desc *desc;
+	size_t i;
+	int r;
+	size_t n_modules =__stop___ofono_module - __start___ofono_module;
+
+	DBG("");
+
+	for (i = 0; i < n_modules; i++) {
+		desc = __start___ofono_module + i;
+		r = desc->init();
+
+		if (r < 0) {
+			ofono_error("Module %s failed to start: %s(%d)",
+					desc->name, strerror(-r), -r);
+			return r;
+		}
+	}
+
+	return 0;
+}
+
+void __ofono_modules_cleanup(void)
+{
+	struct ofono_module_desc *desc;
+	size_t i;
+	size_t n_modules = __stop___ofono_module - __start___ofono_module;
+
+	l_debug("");
+
+	for (i = n_modules; i > 0; i--) {
+		desc = __start___ofono_module + i - 1;
+		desc->exit();
+	}
+}
diff --git a/src/ofono.h b/src/ofono.h
index 2e51776b..e289ff08 100644
--- a/src/ofono.h
+++ b/src/ofono.h
@@ -28,9 +28,6 @@
 
 void __ofono_exit(void);
 
-int __ofono_manager_init(void);
-void __ofono_manager_cleanup(void);
-
 int __ofono_handsfree_audio_manager_init(void);
 void __ofono_handsfree_audio_manager_cleanup(void);
 
@@ -97,6 +94,25 @@ gboolean __ofono_watchlist_remove_item(struct ofono_watchlist *watchlist,
 					unsigned int id);
 void __ofono_watchlist_free(struct ofono_watchlist *watchlist);
 
+struct ofono_module_desc {
+	const char *name;
+	int (*init)(void);
+	void (*exit)(void);
+} __attribute__((aligned(8)));
+
+#define OFONO_MODULE(name, init, exit)					\
+	_Pragma("GCC diagnostic push")					\
+	_Pragma("GCC diagnostic ignored \"-Wattributes\"")		\
+	static struct ofono_module_desc __ofono_module_ ## name		\
+		__attribute__((used, retain, section("__ofono_module"),	\
+			       aligned(8))) = {				\
+			#name, init, exit				\
+		};							\
+	_Pragma("GCC diagnostic pop")
+
+int __ofono_modules_init(void);
+void __ofono_modules_cleanup(void);
+
 #include <ofono/plugin.h>
 
 int __ofono_plugin_init(const char *pattern, const char *exclude);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 04/15] doc: docs for intermediate provisioning db format
  2023-12-19 18:36 [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
  2023-12-19 18:36 ` [PATCH v2 02/15] include: Allow multiple context types Denis Kenzior
  2023-12-19 18:37 ` [PATCH v2 03/15] module: Add support for ofono modules Denis Kenzior
@ 2023-12-19 18:37 ` Denis Kenzior
  2023-12-19 18:37 ` [PATCH v2 05/15] tools: Add provision.py Denis Kenzior
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2023-12-19 18:37 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

Introduce a new provisioning file format to be used by oFono.  This
format will be an 'intermediate' format, that will be converted to a
binary format for use on the actual device.  This allows expensive and
error prone (not to mention hard to secure) parsing of XML files
(such asmobile-broadband-provider-info or Android apns-conf.xml) to be
avoided.

JSON was chosen since it is a much more readable format compared to
XML.
---
 doc/provision.rst | 139 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 139 insertions(+)
 create mode 100644 doc/provision.rst

diff --git a/doc/provision.rst b/doc/provision.rst
new file mode 100644
index 00000000..693b38a3
--- /dev/null
+++ b/doc/provision.rst
@@ -0,0 +1,139 @@
+Carrier Settings Provisioning Database
+======================================
+
+Carrier settings provisioning is performed automatically whenever a new,
+not previously used SIM card is detected for the first time.  Settings such as
+APN, username, password settings as well as the default bearer settings can be
+provisioned automatically if a matching database entry is found.
+
+Matches are performed based on the following information:
+    * SIM Mobile Country Code (MCC)
+    * SIM Mobile Network Code (MNC)
+    * SIM Service Provider Name (SPN)
+
+The carrier settings provisioning database is represented in JSON format and is
+converted to a binary format at installation time.
+
+JSON Structure
+--------------
+**(List):**
+    List of mobile network provider objects.  Top level element.
+
+    Example:
+    ``[{"name": "Operator XYZ", ...}, {"name": "Operator ZYX", ...}]``
+
+    - **name (String):**
+        The name of the mobile network provider.  This field is a freeform
+        string that identifies the provider.  This field is used purely for
+        human consumption and not used by the provisioning logic.
+
+        This field is `required`.
+
+        Example: "Operator XYZ"
+
+    - **ids (List of Strings):**
+        Unique identifiers associated with the mobile network provider.  This
+        is a list of all MCC+MNC identifiers associated with this provider.
+
+        This field is `required`.
+
+        Example: ``["99955", "99956", "99901", "99902"]``
+
+    - **spn (String):**
+        Service Provider Name associated with the mobile network provider.  This
+        field is typically used to differentiate MVNOs from non-MVNO providers.
+
+        This field is `optional`.
+
+        Example: "ZYX"
+
+    - **apns (List):**
+        List of access points associated with the mobile network provider.  At
+        least one entry must be present in the list.
+
+        This field is `required`.
+
+        - **name (String):**
+            The descriptive name of the access point.  If present, will be
+            reflected in the oFono context name after successful provisioning.
+
+            This field is `optional`.
+
+            Example: "Internet"
+
+        - **apn (String):**
+            Access Point Name - Setting required for successful bearer
+            activation.  Provided by the carrier.
+
+            This field is `required`.
+
+            Example: "internet"
+
+        - **type (List of Strings):**
+            The types of connections supported by the access point.  The
+            following types are recognized:
+
+            - "internet": Used for general internet access.
+            - "mms": Used for Multimedia Messaging Service (MMS).
+            - "wap": Used for Wireless Application Protocol (WAP).
+            - "ims": Used for IP Multimedia Subsystem (IMS).
+            - "supl": Used for Secure User Plane Location (SUPL).
+            - "ia": Used for Initial Attach in LTE networks.
+
+            This field is `required`.
+
+            Example: ``["internet", "mms"]``
+
+        - **authentication (String):**
+            Authentication method used for the connection.  The following types
+            are recognized:
+
+            - "chap": CHAP authentication
+            - "pap": PAP authentication
+            - "none": No authentication is used
+
+            This field is `optional`.
+
+            Example: "none"
+
+        - **username (String):**
+            Username used for autenticating to the access point.
+
+            This field is `optional`.
+
+            Example: "username"
+
+        - **password (String):**
+            Password used for autenticating to the access point.
+
+            This field is `optional`.
+
+            Example: "temp123"
+
+        - **protocol (String):**
+            Network protocol used for the connection.  The following types are
+            recognized:
+
+            - "ipv4": IPv4 only
+            - "ipv6": IPv6 only
+            - "ipv4v6": Dual protocol, both IPv4 and IPv6 will be negotiated
+
+            If omitted, then `"ipv4v6"` will be assumed.
+
+            This field is `optional`.
+
+            Example: "ipv4"
+
+        - **mmsc (String):**
+            Multimedia Messaging Service Center - URL for MMS.
+
+            This field is `required` for MMS contexts.
+
+            Example: "foobar.mmsc:80"
+
+        - **mmsproxy (String):**
+            Proxy server for Multimedia Messaging Service (MMS).
+
+            This field is `optional`.
+
+            Example: "mms.proxy.net"
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 05/15] tools: Add provision.py
  2023-12-19 18:36 [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
                   ` (2 preceding siblings ...)
  2023-12-19 18:37 ` [PATCH v2 04/15] doc: docs for intermediate provisioning db format Denis Kenzior
@ 2023-12-19 18:37 ` Denis Kenzior
  2023-12-19 18:37 ` [PATCH v2 06/15] core: Add utilities to read the provisioning db Denis Kenzior
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2023-12-19 18:37 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

Introduce a new tool that will convert the intermediate JSON format
(documented in doc/provision.rst) to the binary provisioning format,
which will be used by ofonod's default provisioning plugin for
automatically setting up carrier specific settings.

The tool also supports import of and conversion of
'mobile-broadband-provider-info' XML files to the new intermediate JSON
file format.  This is accomplished using:
  % tools/provisiontool mbpi-convert --outfile=provision.json

Conversion of JSON intermediate format to binary format is accomplished
using:
  % tools/provisiontool generate --infile=provision.json

By default, the output will be placed in the same directory in the file
'provision.db'.  Alternatively, the output file can be specified using
the --outfile option.

Finally, the tool supports a simple selftest method, which can be
invoked as follows:
  % tools/provisiontool selftest
---
 tools/provisiontool | 727 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 727 insertions(+)
 create mode 100755 tools/provisiontool

v2
- Changed the name to tools/provisiontool instead of
  tools/provision.py

diff --git a/tools/provisiontool b/tools/provisiontool
new file mode 100755
index 00000000..79273277
--- /dev/null
+++ b/tools/provisiontool
@@ -0,0 +1,727 @@
+#!/usr/bin/python3
+#
+# oFono - Open Source Telephony
+# Copyright (C) 2023  Cruise, LLC
+#
+# SPDX-License-Identifier: GPL-2.0-only
+import xml.etree.ElementTree as ET
+import sys
+import json
+import bisect
+from argparse import ArgumentParser, FileType
+from pathlib import Path
+import random
+import struct
+import ctypes
+
+class ProviderInfo:
+    sort_order_map = { v : pos for pos, v in
+                      enumerate( ['name',
+                                  'apn',
+                                  'type',
+                                  'protocol',
+                                  'mmsc',
+                                  'mmsproxy',
+                                  'authentication',
+                                  'username',
+                                  'password'] ) }
+
+    @classmethod
+    def rawimport(cls, entry):
+        if 'name' not in entry:
+            raise SystemExit('No name for entry: ' + str(entry))
+
+        info = ProviderInfo(entry['name'])
+
+        for networkid in entry.get('ids', []):
+            if not info.add_id(networkid):
+                raise SystemExit('Invalid network id: ' + str(networkid))
+
+        if 'spn' in entry:
+            if not info.set_spn(entry['spn']):
+                raise SystemExit('Invalid spn: ' + str(spn))
+
+        for apn in entry.get('apns', []):
+            if not info.add_context(apn):
+                raise SystemExit('Invalid apn: ' + str(apn))
+
+        if not info.is_valid():
+            raise SystemExit('Invalid entry: ' + str(entry))
+
+        return info
+
+    def __init__(self, name):
+        self.context_list = []
+        self.mccmnc_list = []
+        self.name = name
+        self.spn = None
+
+    @staticmethod
+    def is_valid_id(id_string, expected_lengths):
+        """
+        Check if the identifier string is valid.
+
+        Parameters:
+        - id_string: The id string to check.
+        - expected_lengths (tuple): A tuple representing the valid range of
+          lengths.
+
+        Returns:
+        - bool: True if the MCC string is valid, False otherwise.
+        """
+        if not id_string.isdigit():
+            return False
+
+        if len(id_string) not in expected_lengths:
+            return False
+
+        if int(id_string) == 0:
+            return False
+
+        return True
+
+    def add_mccmnc(self, mcc, mnc):
+        if not self.is_valid_id(mcc, (3,)) or not self.is_valid_id(mnc, (2, 3)):
+            return False
+
+        bisect.insort(self.mccmnc_list, mcc + mnc)
+        return True
+
+    def add_id(self, mccmnc):
+        if not self.is_valid_id(mccmnc, (5,6)):
+            return False
+
+        if int(mccmnc[:3]) == 0 or int(mccmnc[3:]) == 0:
+            return False
+
+        bisect.insort(self.mccmnc_list, mccmnc)
+        return True
+
+    def set_spn(self, spn):
+        if len(spn) == 0 or len(spn) > 254:
+            return False
+
+        self.spn = spn
+        return True
+
+    def add_context(self, info):
+        info = dict(sorted(info.items(),
+                      key = lambda pair: self.sort_order_map[pair[0]]))
+        self.context_list.append(info)
+
+        return True
+
+    def is_valid(self):
+        return len(self.context_list) and len(self.mccmnc_list)
+
+    def __str__(self):
+        s = 'Provider \'' + self.name + '\''
+
+        if (self.spn != None):
+            s += ' [SPN:\'' + self.spn + '\']'
+
+        s+= ' ' + str(self.mccmnc_list) + '\n'
+
+        for context in self.context_list:
+            s += '\t' + str(context) + '\n'
+
+        return s
+
+class MobileBroadbandProviderInfo:
+    usage_to_type = { 'internet' : ['internet'],
+                        'mms' : ['mms'],
+                        'wap' : ['wap'],
+                        'mms-internet-hipri' : ['internet', 'mms'],
+                        'mms-internet-hipri-fota' : ['internet','mms'],
+                     }
+    @classmethod
+    def type_from_usage(cls, usage):
+        return cls.usage_to_type[usage]
+
+    def __init__(self, xml_path):
+        self.tree = ET.parse(xml_path)
+
+    def parse(self, xml_path):
+        providers = []
+
+        try:
+            tree = ET.parse(xml_path)
+            root = tree.getroot()
+
+            for provider in root.findall('.//provider'):
+                name = provider.find('name')
+                if name is None or not name.text:
+                    continue;
+
+                info = ProviderInfo(name.text)
+
+                for networkid in provider.findall('gsm/network-id'):
+                    info.add_mccmnc(networkid.get('mcc'), networkid.get('mnc'))
+
+                for apn in provider.findall('gsm/apn'):
+                    context = {}
+
+                    context['apn'] = apn.get('value')
+                    if context['apn'] == None:
+                        continue
+
+                    # Usage is missing for some APNs, skip such contexts for now
+                    usage = apn.find('usage')
+                    if usage is None or usage.get('type') is None:
+                        continue;
+
+                    context['type'] = self.type_from_usage(usage.get('type'))
+                    if context['type'] == None:
+                        sys.stderr.write("Unable to convert type: %s\n" %
+                                            usage.get('type'))
+                        continue
+
+                    if 'mms' in context['type']:
+                        mmsc = apn.find('mmsc')
+
+                        # Ignore MMS contexts with no MMSC since it is needed
+                        # to send messages
+                        if mmsc is None or not mmsc.text:
+                            continue
+
+                        context['mmsc'] = mmsc.text
+
+                        mmsproxy = apn.find('mmsproxy')
+                        if mmsproxy is not None and mmsproxy.text:
+                            context['mmsproxy'] = mmsproxy.text
+
+                    username = apn.find('username')
+                    if username is not None and username.text:
+                        context['username'] = username.text
+
+                    password = apn.find('password')
+                    if password is not None and password.text:
+                        context['password'] = password.text
+
+                    authentication = apn.find('authentication')
+                    if authentication is not None:
+                        context['authentication'] = authentication.get('method')
+
+                    context_name = apn.find('name')
+                    if context_name != None:
+                        context['name'] = context_name.text
+
+                    info.add_context(context)
+
+                if info.is_valid():
+                    providers.append(info)
+
+        except ET.ParseError as e:
+            print(f"Error parsing XML: {e}")
+
+        return providers
+
+class ProvisionContext(ctypes.LittleEndianStructure):
+    _pack_ = 1
+    _fields_ = [
+        ('type', ctypes.c_uint32),
+        ('protocol', ctypes.c_uint32),
+        ('authentication', ctypes.c_uint32),
+        ('reserved', ctypes.c_uint32),
+        ('name_offset', ctypes.c_uint64),
+        ('apn_offset', ctypes.c_uint64),
+        ('username_offset', ctypes.c_uint64),
+        ('password_offset', ctypes.c_uint64),
+        ('mmsproxy_offset', ctypes.c_uint64),
+        ('mmsc_offset', ctypes.c_uint64)
+    ]
+
+    authentication_dict = { 'chap' : 0, 'pap' : 1, 'none' : 2 }
+    protocol_dict = { 'ipv4' : 0, 'ipv6' : 1, 'ipv4v6' : 2 }
+    attrs = ['name', 'apn', 'username', 'password', 'mmsproxy', 'mmsc']
+
+    @classmethod
+    def type_to_context_type(cls, types):
+        r = 0
+
+        for t in types:
+            if t == 'internet':
+                r |= 0x0001
+            elif t == 'mms':
+                r |= 0x0002
+            elif t == 'wap':
+                r |= 0x0004
+            elif t == 'ims':
+                r |= 0x0008
+            elif t == 'supl':
+                r |= 0x0010
+            elif t == 'ia':
+                r |= 0x0020
+
+        return r
+
+    def __init__(self, apn, strings):
+        self.type = self.type_to_context_type(apn['type'])
+        self.protocol = self.protocol_dict[apn.get('protocol', 'ipv4v6')]
+        self.authentication = self.authentication_dict[apn.get('authentication',
+                                                               'chap')]
+
+        for s in self.attrs:
+            offset = strings.add_string(apn.get(s, None))
+            setattr(self, s + '_offset', offset)
+
+class ProvisionData(ctypes.LittleEndianStructure):
+    _pack_ = 1
+    _fields_ = [
+        ('spn_offset', ctypes.c_uint64),
+        ('context_offset', ctypes.c_uint64)
+    ]
+
+    def __init__(self, spn, offset, strings):
+        self.spn_offset = strings.add_string(spn)
+        self.context_offset = offset
+
+class ProvisionNode(ctypes.LittleEndianStructure):
+    _pack_ = 1
+    _fields_ = [
+        ('bit_offsets', ctypes.c_uint64 * 2),
+        ('mccmnc', ctypes.c_uint32),
+        ('diff', ctypes.c_int32),
+        ('provision_data_count', ctypes.c_uint64)
+    ]
+
+    style = "bold"
+    fmt_connection = '\t"%s/%d" -> "%s/%d"[color="#%06x"];\n'
+    fmt_declaration = '\t"%s/%d"[style=%s, color="#%06x"];\n'
+    red = 0xff0000
+    green = 0x00ff00
+
+    def __init__(self, key, diff):
+        self.bit = [None, None]
+        self.key = key
+        self.diff = diff
+        self.entries = {}
+        self.node_offset = 0
+
+    def choose(self, key):
+        return (key >> (31 - self.diff)) & 1
+
+    def print_graphviz(self, f):
+        f.write(self.fmt_declaration % (format(self.key, '032b'),
+                                        self.diff, self.style,
+                                        random.randint(0, 0x00ffffff)))
+        f.write(self.fmt_connection % (format(self.key, '032b'), self.diff,
+                                       format(self.bit[0].key, '032b'),
+                                       self.bit[0].diff, self.red))
+        f.write(self.fmt_connection % (format(self.key, '032b'), self.diff,
+                                       format(self.bit[1].key, '032b'),
+                                       self.bit[1].diff, self.green))
+
+        if (self.diff < self.bit[0].diff):
+            self.bit[0].print_graphviz(f)
+
+        if (self.diff < self.bit[1].diff):
+            self.bit[1].print_graphviz(f)
+
+    def __str__(self):
+        s = format(self.key, '032b') + '/' + str(self.diff)
+        return s
+
+class MccMncTree:
+    @staticmethod
+    def clz(v):
+        count = 32
+        while count and v:
+            v = v >> 1
+            count = count - 1
+
+        return count
+
+    @staticmethod
+    def diff(key1, key2):
+        xor = key1 ^ key2;
+        return MccMncTree.clz(xor)
+
+    def __init__(self):
+        self.root = ProvisionNode(key = 0, diff = -1)
+        self.root.bit[0] = self.root
+        self.root.bit[1] = self.root
+        self.n_nodes = 1
+
+    def print_graphviz(self):
+        f = open("step%d.dot" % self.n_nodes, "w")
+        # Use 'dot -Tx11' to visualize
+        f.write('digraph trie {\n')
+        self.root.print_graphviz(f)
+        f.write('}\n')
+        f.close()
+
+    def find_closest(self, key):
+        parent = self.root
+        child = self.root.bit[0]
+
+        while parent.diff < child.diff:
+            parent = child
+            child = child.bit[child.choose(key)]
+
+        return child
+
+    def find(self, key):
+        found = self.find_closest(key)
+        if found.key == key:
+            return found
+
+        return None
+
+    def insert(self, key, attr, value):
+        node = self.find_closest(key);
+        if node.key == key:
+            node.entries[attr] = value
+            return
+
+        bit = self.diff(node.key, key)
+        parent = self.root
+        child = self.root.bit[0]
+
+        while (parent.diff < child.diff) and (child.diff < bit):
+            parent = child
+            child = child.bit[child.choose(key)]
+
+        node = ProvisionNode(key, bit)
+        bit = node.choose(key)
+        node.bit[bit] = node
+        node.bit[not bit] = child
+
+        node.entries[attr] = value
+
+        if parent == self.root:
+            self.root.bit[0] = node
+        else:
+            bit = parent.choose(key)
+            parent.bit[bit] = node
+
+        self.n_nodes += 1
+
+    def traverse_recursive(self, node, bit, visitor):
+        if node == self.root:
+            return
+
+        if node.diff <= bit:
+            visitor.visit(node)
+            return
+
+        self.traverse_recursive(node.bit[0], node.diff, visitor)
+        self.traverse_recursive(node.bit[1], node.diff, visitor)
+
+    def traverse(self, visitor):
+        self.traverse_recursive(self.root.bit[0], -1, visitor)
+
+class StringAccumulator:
+    def __init__(self):
+        self.data = bytearray(b'\x00') # So offsets are never 0 used for NULL
+        self.offsets = {}
+
+    def add_string(self, s):
+        if s is None:
+            return 0
+
+        if s in self.offsets:
+            return self.offsets[s]
+
+        offset = len(self.data)
+        self.data.extend(s.encode('utf-8'))
+        self.data.append(0)
+        self.offsets[s] = offset
+
+        return offset
+
+    def get_bytes(self):
+        return self.data
+
+class ProvisionDatabase(ctypes.LittleEndianStructure):
+    _pack_ = 1
+    _fields_ = [
+        ('version', ctypes.c_uint64),
+        ('file_size', ctypes.c_uint64),
+        ('header_size', ctypes.c_uint64),
+        ('node_struct_size', ctypes.c_uint64),
+        ('provision_data_struct_size', ctypes.c_uint64),
+        ('context_struct_size', ctypes.c_uint64),
+        ('nodes_offset', ctypes.c_uint64),
+        ('nodes_size', ctypes.c_uint64),
+        ('contexts_offset', ctypes.c_uint64),
+        ('contexts_size', ctypes.c_uint64),
+        ('strings_offset', ctypes.c_uint64),
+        ('strings_size', ctypes.c_uint64)
+    ]
+
+    class CalculateNodeOffsetVisitor:
+        def __init__(self):
+            self.current_offset = 0
+        def visit(self, node):
+            node.node_offset = self.current_offset
+
+            # Node data is followed by at least one ProvisionData object, with
+            # the only exception being root, which has no data by definition
+            self.current_offset += ctypes.sizeof(ProvisionNode)
+            self.current_offset += (ctypes.sizeof(ProvisionData) *
+                                    len(node.entries))
+
+    class SerializeVisitor:
+        def __init__(self, buffer):
+            self.buffer = buffer
+
+        def visit(self, node):
+            # Node doesn't quite fit the C structure definition, so do this
+            # manually by using struct.pack
+            self.buffer.extend(struct.pack('<QQIiQ',
+                                           node.bit[0].node_offset,
+                                           node.bit[1].node_offset,
+                                           node.key, node.diff,
+                                           len(node.entries)))
+
+            for spn in sorted(node.entries):
+                pd = node.entries[spn]
+                self.buffer.extend(bytes(pd))
+
+    def __init__(self, provider_infos):
+        self.strings = StringAccumulator()
+        self.contexts = bytearray()
+        self.tree = MccMncTree()
+
+        for info in provider_infos:
+            pd = ProvisionData(info.spn, len(self.contexts), self.strings)
+
+            self.contexts.extend(struct.pack('<Q', len(info.context_list)))
+
+            for context in info.context_list:
+                self.contexts.extend(bytes(ProvisionContext(context,
+                                                            self.strings)))
+
+            for mccmnc in info.mccmnc_list:
+                # Sort None spns as '' so they're first in the list when
+                # the SerializeVisitor sorts the entries dict
+                spn = info.spn if info.spn is not None else ''
+
+                # 2 and 3 byte MNCs are treated differently, even if evaluate
+                # to the same integer.  For example, 02 and 002 are different
+                # MNCs.  In practice this doesn't actually happen except on
+                # test networks, but account for this possibility by using the
+                # upper 10 bits for the MCC, followed by a single bit which
+                # signifies whether a 3 byte MNC is used, followed by 10 bits
+                # of the MNC
+                key = int(mccmnc[:3]) << 11 | int(mccmnc[3:])
+                if len(mccmnc[3:]) == 3:
+                    key |= 1 << 10
+
+                self.tree.insert(key, spn, pd)
+
+        visitor = self.CalculateNodeOffsetVisitor()
+        visitor.visit(self.tree.root)
+        self.tree.traverse(visitor)
+
+        self.version = 1
+        self.header_size = ctypes.sizeof(ProvisionDatabase)
+        self.file_size = self.header_size
+        self.node_struct_size = ctypes.sizeof(ProvisionNode)
+        self.provision_data_struct_size = ctypes.sizeof(ProvisionData)
+        self.context_struct_size = ctypes.sizeof(ProvisionContext)
+        self.nodes_offset = self.header_size
+        self.nodes_size = visitor.current_offset
+        self.file_size += self.nodes_size
+        self.contexts_offset = self.nodes_offset + self.nodes_size
+        self.contexts_size = len(self.contexts)
+        self.file_size += self.contexts_size
+        self.strings_offset = self.contexts_offset + self.contexts_size
+        self.strings_size = len(self.strings.get_bytes())
+        self.file_size += self.strings_size
+
+    def serialize(self):
+        buffer = bytearray()
+        buffer.extend(bytes(self))
+
+        visitor = self.SerializeVisitor(buffer)
+        visitor.visit(self.tree.root)
+        self.tree.traverse(visitor)
+
+        buffer.extend(self.contexts)
+        buffer.extend(self.strings.get_bytes())
+
+        return buffer
+
+class ProviderInfoJSONEncoder(json.JSONEncoder):
+    def default(self, obj):
+        if isinstance(obj, ProviderInfo):
+            asdict = { 'name' : obj.name, 'ids' : obj.mccmnc_list }
+
+            if (obj.spn != None):
+                asdict['spn'] = obj.spn
+
+            asdict.update({'apns' : obj.context_list})
+            return asdict
+
+        return json.JSONEncoder.default(self, obj)
+
+def mbpi_convert(args):
+    xml_path = '/usr/share/mobile-broadband-provider-info/serviceproviders.xml'
+    mbpi = MobileBroadbandProviderInfo(xml_path)
+    provider_infos = mbpi.parse(xml_path)
+
+    try:
+        if args.outfile is None:
+            out = sys.stdout
+        else:
+            out = args.outfile.open('w', encoding='utf-8')
+
+        with out as outfile:
+            json.dump(provider_infos, outfile, ensure_ascii=False, indent=2,
+                      cls=ProviderInfoJSONEncoder)
+    except ValueError as e:
+        raise SystemExit(e)
+
+def generate(args):
+    try:
+        json_dict = json.load(args.infile)
+    except ValueError as e:
+        raise SystemExit(e)
+
+    provider_infos = []
+
+    for entry in json_dict:
+        info = ProviderInfo.rawimport(entry)
+        provider_infos.append(info)
+
+    db = ProvisionDatabase(provider_infos)
+    with args.outfile.open('wb') as outfile:
+        outfile.write(db.serialize())
+
+def selftest(args):
+    tree = MccMncTree()
+
+    # Generate random key this many times and insert it into the tree
+    # There will be some collisions, so count the number of items inserted
+    # Then run the lookup and make sure the same number of items can be found
+    times = 100000
+    for i in range(0, times):
+        key = random.randint(10000, 999999)
+        tree.insert(key, None, None)
+
+    n_inserted = tree.n_nodes
+    print("Created a tree with %d nodes (1 root)" % n_inserted)
+
+    n_found = 0
+    expected_keys = []
+
+    for i in range(10000, 1000000):
+        if tree.find(i):
+            n_found += 1
+            expected_keys.append(i)
+
+    expected_keys = sorted(expected_keys)
+
+    print("Found %d nodes (not including root)" % n_found)
+    assert n_found == n_inserted - 1
+
+    class GetKeysVisitor:
+        def __init__(self):
+            self.keys = []
+
+        def visit(self, node):
+            self.keys.append(node.key)
+
+    visitor = GetKeysVisitor()
+    tree.traverse(visitor)
+    assert visitor.keys == expected_keys
+
+    sample_json = """[
+    {
+      "name": "Operator XYZ",
+      "ids": [
+        "99955", "99956", "99901", "99902"
+      ],
+      "apns": [
+        {
+          "name": "Internet",
+          "apn": "internet",
+          "type": [
+            "internet"
+          ],
+          "authentication": "none",
+          "protocol": "ipv4"
+        },
+        {
+          "name": "IMS+MMS",
+          "apn": "imsmms",
+          "type": [
+            "ims", "mms"
+          ],
+          "mmsc": "foobar.mmsc:80",
+          "mmsproxy": "mms.proxy.net",
+          "authentication": "pap",
+          "protocol": "ipv6"
+        }
+      ]
+    },
+    {
+      "name": "Operator ZYX",
+      "ids": [
+        "99998", "99999", "99901", "99902"
+      ],
+      "spn": "ZYX",
+      "apns": [
+        {
+          "name": "ZYX",
+          "apn": "zyx",
+          "type": [
+            "internet"
+          ],
+          "authentication": "none",
+          "protocol": "ipv4"
+        }
+      ]
+    }
+    ]"""
+    try:
+        json_dict = json.loads(sample_json)
+    except ValueError as e:
+        raise SystemExit(e)
+
+    provider_infos = []
+
+    for entry in json_dict:
+        info = ProviderInfo.rawimport(entry)
+        provider_infos.append(info)
+
+    db = ProvisionDatabase(provider_infos)
+    expected_strings = bytearray(b'\x00Internet\x00internet\x00IMS+MMS\x00' +
+                b'imsmms\x00mms.proxy.net\x00foobar.mmsc:80\x00ZYX\x00zyx\x00')
+    assert(expected_strings == db.strings.get_bytes())
+
+    with open('sample.db', 'wb') as outfile:
+        outfile.write(db.serialize())
+
+if __name__ == "__main__":
+    parser = ArgumentParser(description='Parse command line arguments')
+    subparsers = parser.add_subparsers(title='subcommands', dest='command')
+
+    # mbpi-convert command
+    mbpi_convert_parser = subparsers.add_parser('mbpi-convert',
+                        help='Convert mobile-broadband-provider-info database')
+    mbpi_convert_parser.add_argument('--outfile', type=Path, default=None,
+                        help='Output file path', required=False,)
+    mbpi_convert_parser.set_defaults(func=mbpi_convert)
+
+    # generate command
+    generate_parser = subparsers.add_parser('generate',
+                                            help='Generate binary provider db')
+    generate_parser.add_argument('--outfile', type=Path, default='provision.db',
+                                 help='Output file path', required=False)
+    generate_parser.add_argument('--infile', type=FileType(encoding='utf-8'),
+                                 help='Input JSON db', default=sys.stdin)
+    generate_parser.set_defaults(func=generate)
+
+    # selftest command
+    selftest_parser = subparsers.add_parser('selftest',
+                        help='Run self-tests')
+    selftest_parser.set_defaults(func=selftest)
+
+    args = parser.parse_args()
+    if hasattr(args, 'func'):
+        args.func(args)
+    else:
+        parser.print_help()
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 06/15] core: Add utilities to read the provisioning db
  2023-12-19 18:36 [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
                   ` (3 preceding siblings ...)
  2023-12-19 18:37 ` [PATCH v2 05/15] tools: Add provision.py Denis Kenzior
@ 2023-12-19 18:37 ` Denis Kenzior
  2023-12-19 18:37 ` [PATCH v2 07/15] tools: lookup-apn: Use the new provision_db utils Denis Kenzior
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2023-12-19 18:37 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

Binary provisioning format is based on a patricia trie / crit-bit tree,
with each MCC + MNC combination represented by a single node.  Each node
contains an array of { SPN, offset } pairs, with the offset pointing to
the region of memory where the context information resides.

Each node also has two offsets, corresponding to left and right children
of the node, as well as the position of the critical bit, based on which
the tree is traversed.

All strings are placed in the last section and are nil terminated.
Structures are designed with 8-byte alignment and stored in little
endian format, which will require no conversion for the vast majority of
platforms in use.
---
 Makefile.am       |   3 +-
 src/provisiondb.c | 439 ++++++++++++++++++++++++++++++++++++++++++++++
 src/provisiondb.h |  18 ++
 3 files changed, 459 insertions(+), 1 deletion(-)
 create mode 100644 src/provisiondb.c
 create mode 100644 src/provisiondb.h

v2

- Changed license to LGPL in case the provisiondb code needs to be
  linked against in other applications.
- Moved provisiondb utilities to the core

diff --git a/Makefile.am b/Makefile.am
index f7b59a47..b3a016cf 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -726,7 +726,8 @@ src_ofonod_SOURCES = $(builtin_sources) $(gatchat_sources) src/ofono.ver \
 			src/hfp.h src/siri.c \
 			src/netmon.c src/lte.c src/ims.c \
 			src/netmonagent.c src/netmonagent.h \
-			src/module.c
+			src/module.c \
+			src/provisiondb.h src/provisiondb.c
 
 src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) $(ell_ldadd) \
 			@GLIB_LIBS@ @DBUS_LIBS@ -ldl
diff --git a/src/provisiondb.c b/src/provisiondb.c
new file mode 100644
index 00000000..0fa454c9
--- /dev/null
+++ b/src/provisiondb.c
@@ -0,0 +1,439 @@
+/*
+ *  oFono - Open Source Telephony
+ *  Copyright (C) 2023  Cruise, LLC
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <linux/types.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <ell/ell.h>
+
+#define OFONO_API_SUBJECT_TO_CHANGE
+#include <ofono/modem.h>
+#include <ofono/gprs-provision.h>
+
+#include "provisiondb.h"
+
+struct provision_header {
+	__le64 version;
+	__le64 file_size;
+	__le64 header_size;
+	__le64 node_struct_size;
+	__le64 provision_data_struct_size;
+	__le64 context_struct_size;
+	__le64 nodes_offset;
+	__le64 nodes_size;
+	__le64 contexts_offset;
+	__le64 contexts_size;
+	__le64 strings_offset;
+	__le64 strings_size;
+
+	/* followed by nodes_size of node structures */
+	/* followed by contexts_size of context structures */
+	/* followed by strings_size packed strings */
+} __attribute__((packed));
+
+struct node {
+	__le64 bit_offsets[2];
+	__le32 mccmnc;
+	__le32 diff; /* Signed */
+	__le64 provision_data_count;
+	/* followed by provision_data_count provision_data structures */
+} __attribute__((packed));
+
+struct provision_data {
+	__le64 spn_offset;
+	__le64 context_offset;	/* the offset contains count of contexts */
+				/* followed by context structures */
+} __attribute__((packed));
+
+struct context {
+	__le32 type; /* Corresponds to ofono_gprs_context_type bitmap */
+	__le32 protocol; /* Corresponds to ofono_gprs_proto */
+	__le32 authentication; /* Corresponds to ofono_gprs_auth_method */
+	__le32 reserved;
+	__le64 name_offset;
+	__le64 apn_offset;
+	__le64 username_offset;
+	__le64 password_offset;
+	__le64 mmsproxy_offset;
+	__le64 mmsc_offset;
+} __attribute__((packed));
+
+struct provision_db {
+	int fd;
+	time_t mtime;
+	size_t size;
+	void *addr;
+	uint64_t nodes_offset;
+	uint64_t nodes_size;
+	uint64_t contexts_offset;
+	uint64_t contexts_size;
+	uint64_t strings_offset;
+	uint64_t strings_size;
+};
+
+struct provision_db *provision_db_new(const char *pathname)
+{
+	struct provision_header *hdr;
+	struct provision_db *pdb = NULL;
+	struct stat st;
+	void *addr;
+	size_t size;
+	int fd;
+
+	if (!pathname)
+		return NULL;
+
+	fd = open(pathname, O_RDONLY | O_CLOEXEC);
+	if (fd < 0)
+		return NULL;
+
+	if (fstat(fd, &st) < 0)
+		goto error_close;
+
+	size = st.st_size;
+	if (size < sizeof(struct provision_header))
+		goto error_close;
+
+	addr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
+	if (addr == MAP_FAILED)
+		goto error_close;
+
+	hdr = addr;
+
+	if (L_LE64_TO_CPU(hdr->file_size) != size)
+		goto failed;
+
+	if (L_LE64_TO_CPU(hdr->header_size) != sizeof(struct provision_header))
+		goto failed;
+
+	if (L_LE64_TO_CPU(hdr->node_struct_size) != sizeof(struct node))
+		goto failed;
+
+	if (L_LE64_TO_CPU(hdr->provision_data_struct_size) !=
+			sizeof(struct provision_data))
+		goto failed;
+
+	if (L_LE64_TO_CPU(hdr->context_struct_size) != sizeof(struct context))
+		goto failed;
+
+	if (L_LE64_TO_CPU(hdr->header_size) + L_LE64_TO_CPU(hdr->nodes_size) +
+			L_LE64_TO_CPU(hdr->contexts_size) +
+			L_LE64_TO_CPU(hdr->strings_size) != size)
+		goto failed;
+
+	pdb = l_new(struct provision_db, 1);
+
+	pdb->fd = fd;
+	pdb->mtime = st.st_mtime;
+	pdb->size = size;
+	pdb->addr = addr;
+	pdb->nodes_offset = L_LE64_TO_CPU(hdr->nodes_offset);
+	pdb->nodes_size = L_LE64_TO_CPU(hdr->nodes_size);
+	pdb->contexts_offset = L_LE64_TO_CPU(hdr->contexts_offset);
+	pdb->contexts_size = L_LE64_TO_CPU(hdr->contexts_size);
+	pdb->strings_offset = L_LE64_TO_CPU(hdr->strings_offset);
+	pdb->strings_size = L_LE64_TO_CPU(hdr->strings_size);
+
+	return pdb;
+
+failed:
+	munmap(addr, st.st_size);
+error_close:
+	close(fd);
+	return NULL;
+}
+
+struct provision_db *provision_db_new_default(void)
+{
+	struct provision_db *db = NULL;
+	size_t i;
+	const char * const paths[] = { "/usr/share/ofono/provision.db" };
+
+	for (i = 0; !db && i < L_ARRAY_SIZE(paths); i++)
+		db = provision_db_new(paths[i]);
+
+	return db;
+}
+
+void provision_db_free(struct provision_db *pdb)
+{
+	if (!pdb)
+		return;
+
+	munmap(pdb->addr, pdb->size);
+	close(pdb->fd);
+	l_free(pdb);
+}
+
+static int __get_node(struct provision_db *pdb, uint64_t offset,
+				struct node **out_node)
+{
+	uint64_t count;
+	struct node *node;
+
+	if (offset + sizeof(struct node) > pdb->nodes_size)
+		return -EPROTO;
+
+	node = pdb->addr + pdb->nodes_offset + offset;
+	offset += sizeof(struct node);
+	count = L_LE64_TO_CPU(node->provision_data_count);
+
+	if (offset + count * sizeof(struct provision_data) > pdb->nodes_size)
+		return -EPROTO;
+
+	*out_node = node;
+	return 0;
+}
+
+static struct provision_data *__get_provision_data(struct node *node)
+{
+	return ((void *) node) + sizeof(struct node);
+}
+
+static int __get_string(struct provision_db *pdb, uint64_t offset,
+				char **out_str)
+{
+	if (!offset) {
+		*out_str = NULL;
+		return 0;
+	}
+
+	if (offset >= pdb->strings_size)
+		return -EPROTO;
+
+	*out_str = pdb->addr + pdb->strings_offset + offset;
+	return 0;
+}
+
+static int __get_contexts(struct provision_db *pdb, uint64_t offset,
+				struct ofono_gprs_provision_data **contexts,
+				size_t *n_contexts)
+{
+	void *start = pdb->addr + pdb->contexts_offset;
+	uint64_t num;
+	uint64_t i;
+	struct ofono_gprs_provision_data *ret;
+	int r;
+
+	if (offset + sizeof(__le64) >= pdb->contexts_size)
+		return -EPROTO;
+
+	num = l_get_le64(start + offset);
+	offset += sizeof(__le64);
+
+	if (offset + num * sizeof(struct context) > pdb->contexts_size)
+		return -EPROTO;
+
+	ret = l_new(struct ofono_gprs_provision_data, num);
+
+	for (i = 0; i < num; i++, offset += sizeof(struct context)) {
+		struct context *context = start + offset;
+
+		ret[i].type = L_LE32_TO_CPU(context->type);
+		ret[i].proto = L_LE32_TO_CPU(context->protocol);
+		ret[i].auth_method = L_LE32_TO_CPU(context->authentication);
+
+		if ((r = __get_string(pdb, L_LE64_TO_CPU(context->name_offset),
+					&ret[i].name)) < 0)
+			goto fail;
+
+		if ((r = __get_string(pdb, L_LE64_TO_CPU(context->apn_offset),
+					&ret[i].apn)) < 0)
+			goto fail;
+
+		if ((r = __get_string(pdb,
+					L_LE64_TO_CPU(context->username_offset),
+					&ret[i].username)) < 0)
+			goto fail;
+
+		if ((r = __get_string(pdb,
+					L_LE64_TO_CPU(context->password_offset),
+					&ret[i].password)) < 0)
+			goto fail;
+
+		if ((r = __get_string(pdb,
+					L_LE64_TO_CPU(context->mmsproxy_offset),
+					&ret[i].message_proxy)) < 0)
+			goto fail;
+
+		if ((r = __get_string(pdb, L_LE64_TO_CPU(context->mmsc_offset),
+					&ret[i].message_center)) < 0)
+			goto fail;
+	}
+
+	*contexts = ret;
+	*n_contexts = num;
+	return 0;
+
+fail:
+	l_free(ret);
+	return r;
+}
+
+static uint8_t choose(struct node *node, uint32_t key)
+{
+	return (key >> (31U - L_LE32_TO_CPU(node->diff))) & 1;
+}
+
+static int __find(struct provision_db *pdb, uint32_t key,
+						struct node **out_node)
+{
+	struct node *child;
+	struct node *parent;
+	int r;
+
+	r = __get_node(pdb, 0, &parent);
+	if (r < 0)
+		return r;
+
+	r = __get_node(pdb, L_LE64_TO_CPU(parent->bit_offsets[0]), &child);
+	if (r < 0)
+		return r;
+
+	while ((int32_t) L_LE32_TO_CPU(parent->diff) <
+			(int32_t) L_LE32_TO_CPU(child->diff)) {
+		uint8_t bit = choose(child, key);
+		uint64_t offset = L_LE64_TO_CPU(child->bit_offsets[bit]);
+
+		parent = child;
+
+		r = __get_node(pdb, offset, &child);
+		if (r < 0)
+			return r;
+	}
+
+	if (L_LE32_TO_CPU(child->mccmnc) != key)
+		return -ENOENT;
+
+	*out_node = child;
+	return 0;
+}
+
+static int id_as_num(const char *id, size_t len)
+{
+	uint32_t v = 0;
+	size_t i;
+
+	for (i = 0; i < len; i++) {
+		if (!l_ascii_isdigit(id[i]))
+			return -EINVAL;
+
+		v = v * 10 + id[i] - '0';
+	}
+
+	return v;
+}
+
+static int key_from_mcc_mnc(const char *mcc, const char *mnc, uint32_t *key)
+{
+	size_t mcc_len = strlen(mcc);
+	size_t mnc_len = strlen(mnc);
+	uint32_t v;
+	int r;
+
+	if (mcc_len != 3)
+		return -EINVAL;
+
+	if (mnc_len != 2 && mnc_len != 3)
+		return -EINVAL;
+
+	r = id_as_num(mcc, mcc_len);
+	if (r < 0)
+		return r;
+
+	v = r << 11;
+
+	r = id_as_num(mnc, mnc_len);
+	if (r < 0)
+		return r;
+
+	if (mnc_len == 3)
+		v |= 1 << 10;
+
+	v |= r;
+
+	*key = v;
+	return 0;
+}
+
+int provision_db_lookup(struct provision_db *pdb,
+			const char *mcc, const char *mnc, const char *match_spn,
+			struct ofono_gprs_provision_data **items,
+			size_t *n_items)
+{
+	int r;
+	uint32_t key;
+	struct node *node;
+	struct provision_data *data;
+	struct provision_data *found = NULL;
+	uint64_t count;
+	uint64_t i;
+
+	if (pdb == NULL)
+		return -EBADF;
+
+	r = key_from_mcc_mnc(mcc, mnc, &key);
+	if (r < 0)
+		return r;
+
+	/*
+	 * Find the target node, then walk the provision_data items to
+	 * match the spn.  After that it is a matter of allocating the
+	 * return contexts and copying over the details.
+	 */
+
+	r = __find(pdb, key, &node);
+	if (r < 0)
+		return r;
+
+	count = L_LE64_TO_CPU(node->provision_data_count);
+	data = __get_provision_data(node);
+
+	if (!count)
+		return -ENOENT;
+
+	/*
+	 * provision_data objects are sorted by SPN, with no SPN (non-MVNO)
+	 * being first.  Since the provisioning data is imperfect, we try to
+	 * match by SPN, but if that fails, we return the non-SPN entry, if
+	 * present
+	 */
+	if (data[0].spn_offset == 0) {
+		found = data;
+		data += 1;
+		count -= 1;
+	}
+
+	for (i = 0; i < count; i++) {
+		char *spn;
+
+		r = __get_string(pdb, L_LE64_TO_CPU(data[i].spn_offset), &spn);
+		if (r < 0)
+			return r;
+
+		if (l_streq0(spn, match_spn)) {
+			found = data + i;
+			break;
+		}
+	}
+
+	if (!found)
+		return -ENOENT;
+
+	return __get_contexts(pdb, L_LE64_TO_CPU(found->context_offset),
+				items, n_items);
+}
diff --git a/src/provisiondb.h b/src/provisiondb.h
new file mode 100644
index 00000000..d7381b94
--- /dev/null
+++ b/src/provisiondb.h
@@ -0,0 +1,18 @@
+/*
+ *  oFono - Open Source Telephony
+ *  Copyright (C) 2023  Cruise, LLC
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+struct ofono_gprs_provision_data;
+struct provision_db;
+
+struct provision_db *provision_db_new(const char *pathname);
+struct provision_db *provision_db_new_default(void);
+void provision_db_free(struct provision_db *pdb);
+
+int provision_db_lookup(struct provision_db *pdb,
+			const char *mcc, const char *mnc, const char *spn,
+			struct ofono_gprs_provision_data **items,
+			size_t *n_items);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 07/15] tools: lookup-apn: Use the new provision_db utils
  2023-12-19 18:36 [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
                   ` (4 preceding siblings ...)
  2023-12-19 18:37 ` [PATCH v2 06/15] core: Add utilities to read the provisioning db Denis Kenzior
@ 2023-12-19 18:37 ` Denis Kenzior
  2023-12-19 18:37 ` [PATCH v2 08/15] provision: Import initial JSON db Denis Kenzior
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2023-12-19 18:37 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

Migrate lookup-apn tool to use the new provision.db binary file format.

The typical usage is now changed as follows:
  % tools/lookup-apn --file=sample.db 999 02
---
 Makefile.am        |   6 +-
 tools/lookup-apn.c | 173 ++++++++++++++++++++++++++-------------------
 2 files changed, 103 insertions(+), 76 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index b3a016cf..3023ed0c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -661,7 +661,6 @@ builtin_sources += plugins/provision.c
 
 builtin_modules += file_provision
 builtin_sources += plugins/file-provision.c
-
 endif
 
 if MAINTAINER_MODE
@@ -1010,8 +1009,9 @@ tools_auto_enable_LDADD = gdbus/libgdbus-internal.la @GLIB_LIBS@ @DBUS_LIBS@
 tools_get_location_SOURCES = tools/get-location.c
 tools_get_location_LDADD = @GLIB_LIBS@ @DBUS_LIBS@
 
-tools_lookup_apn_SOURCES = plugins/mbpi.c plugins/mbpi.h tools/lookup-apn.c
-tools_lookup_apn_LDADD = @GLIB_LIBS@
+tools_lookup_apn_SOURCES = src/provisiondb.h src/provisiondb.c \
+				tools/lookup-apn.c
+tools_lookup_apn_LDADD = $(ell_ldadd)
 
 tools_tty_redirector_SOURCES = tools/tty-redirector.c
 tools_tty_redirector_LDADD = @GLIB_LIBS@
diff --git a/tools/lookup-apn.c b/tools/lookup-apn.c
index 884b32a0..493187a9 100644
--- a/tools/lookup-apn.c
+++ b/tools/lookup-apn.c
@@ -1,115 +1,142 @@
 /*
- *
  *  oFono - Open Source Telephony
- *
  *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
+ *  Copyright (C) 2023  Cruise, LLC
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- *  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 General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
+ *  SPDX-License-Identifier: GPL-2.0-only
  */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
+#include <stdio.h>
 #include <stdlib.h>
+#include <getopt.h>
+#include <errno.h>
 
-#include <glib.h>
+#include <ell/ell.h>
 
 #define OFONO_API_SUBJECT_TO_CHANGE
 #include <ofono/modem.h>
 #include <ofono/gprs-provision.h>
 
-#include "plugins/mbpi.h"
+#include "provisiondb.h"
 
-static void lookup_apn(const char *match_mcc, const char *match_mnc,
-						gboolean allow_duplicates)
-{
-	GSList *l;
-	GSList *apns;
-	GError *error = NULL;
+static const char *option_file = NULL;
 
-	g_print("Searching for info for network: %s%s\n", match_mcc, match_mnc);
+static int lookup_apn(const char *match_mcc, const char *match_mnc,
+							const char *match_spn)
+{
+	struct provision_db *pdb;
+	struct ofono_gprs_provision_data *contexts;
+	size_t n_contexts;
+	int r;
+	size_t i;
+
+	if (option_file) {
+		fprintf(stdout, "Opening database at: '%s'\n", option_file);
+		pdb = provision_db_new(option_file);
+	} else {
+		fprintf(stdout, "Opening database in default location\n");
+		pdb = provision_db_new_default();
+	}
 
-	apns = mbpi_lookup_apn(match_mcc, match_mnc, allow_duplicates, &error);
+	if (!pdb) {
+		fprintf(stdout, "Database opening failed\n");
+		return -EIO;
+	}
 
-	if (apns == NULL) {
-		if (error != NULL) {
-			g_printerr("Lookup failed: %s\n", error->message);
-			g_error_free(error);
-		}
+	fprintf(stdout, "Searching for info for network: %s%s, spn: %s\n",
+			match_mcc, match_mnc, match_spn ? match_spn : "<None>");
 
-		return;
+	r = provision_db_lookup(pdb, match_mcc, match_mnc, match_spn,
+					&contexts, &n_contexts);
+	if (r < 0) {
+		fprintf(stderr, "Unable to lookup: %s\n", strerror(-r));
+		return r;
 	}
 
-	for (l = apns; l; l = l->next) {
-		struct ofono_gprs_provision_data *ap = l->data;
+	for (i = 0; i < n_contexts; i++) {
+		struct ofono_gprs_provision_data *ap = contexts + i;
+
+		fprintf(stdout, "\nName: %s\n", ap->name);
+		fprintf(stdout, "APN: %s\n", ap->apn);
+		fprintf(stdout, "Type: %x\n", ap->type);
+		fprintf(stdout, "Proto: %x\n", ap->proto);
 
-		g_print("\n");
-		g_print("Name: %s\n", ap->name);
-		g_print("APN: %s\n", ap->apn);
-		g_print("Type: %s\n", mbpi_ap_type(ap->type));
-		g_print("Username: %s\n", ap->username);
-		g_print("Password: %s\n", ap->password);
+		if (ap->username)
+			fprintf(stdout, "Username: %s\n", ap->username);
 
-		mbpi_ap_free(ap);
+		if (ap->password)
+			fprintf(stdout, "Password: %s\n", ap->password);
+
+		if (ap->type & OFONO_GPRS_CONTEXT_TYPE_MMS) {
+			if (ap->message_proxy)
+				fprintf(stdout, "Message Proxy: %s\n",
+							ap->message_proxy);
+			fprintf(stdout, "Message Center: %s\n",
+							ap->message_center);
+		}
 	}
 
-	g_slist_free(apns);
+	l_free(contexts);
+
+	provision_db_free(pdb);
+
+	return 0;
 }
 
-static gboolean option_version = FALSE;
-static gboolean option_duplicates = FALSE;
+static void usage(void)
+{
+	printf("lookup-apn\nUsage:\n");
+	printf("lookup-apn [options] <mcc> <mnc> [spn]\n");
+	printf("Options:\n"
+			"\t-v, --version	Show version\n"
+			"\t-f, --file		Provision DB file to use\n"
+			"\t-h, --help		Show help options\n");
+}
 
-static GOptionEntry options[] = {
-	{ "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
-				"Show version information and exit" },
-	{ "allow-duplicates", 0, 0, G_OPTION_ARG_NONE, &option_duplicates,
-				"Allow duplicate access point types" },
-	{ NULL },
+static const struct option options[] = {
+	{ "version",	no_argument,		NULL, 'v' },
+	{ "help",	no_argument,		NULL, 'h' },
+	{ "file",	required_argument,	NULL, 'f' },
+	{ },
 };
 
 int main(int argc, char **argv)
 {
-	GOptionContext *context;
-	GError *error = NULL;
-
-	context = g_option_context_new(NULL);
-	g_option_context_add_main_entries(context, options, NULL);
-
-	if (g_option_context_parse(context, &argc, &argv, &error) == FALSE) {
-		if (error != NULL) {
-			g_printerr("%s\n", error->message);
-			g_error_free(error);
-		} else
-			g_printerr("An unknown error occurred\n");
-		exit(1);
+	for (;;) {
+		int opt = getopt_long(argc, argv, "f:vh", options, NULL);
+
+		if (opt < 0)
+			break;
+
+		switch (opt) {
+		case 'f':
+			option_file = optarg;
+			break;
+		case 'v':
+			printf("%s\n", VERSION);
+			return EXIT_SUCCESS;
+		case 'h':
+			usage();
+			return EXIT_SUCCESS;
+		default:
+			return EXIT_FAILURE;
+		}
 	}
 
-	g_option_context_free(context);
-
-	if (option_version == TRUE) {
-		g_print("%s\n", VERSION);
-		exit(0);
+	if (argc - optind > 3) {
+		fprintf(stderr, "Invalid command line parameters\n");
+		return EXIT_FAILURE;
 	}
 
-	if (argc < 2) {
-		g_printerr("Missing parameters\n");
-		exit(1);
+	if (argc - optind < 2) {
+		fprintf(stderr, "Missing MCC MNC parameters\n");
+		return EXIT_FAILURE;
 	}
 
-	lookup_apn(argv[1], argv[2], option_duplicates);
-
-	return 0;
+	return lookup_apn(argv[optind], argv[optind + 1],
+			argc - optind == 3 ? argv[optind + 2] : NULL);
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 08/15] provision: Import initial JSON db
  2023-12-19 18:36 [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
                   ` (5 preceding siblings ...)
  2023-12-19 18:37 ` [PATCH v2 07/15] tools: lookup-apn: Use the new provision_db utils Denis Kenzior
@ 2023-12-19 18:37 ` Denis Kenzior
  2023-12-19 18:37 ` [PATCH v2 09/15] provision: Add new module Denis Kenzior
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2023-12-19 18:37 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

This database is based on mobile-broadband-provider-info, which is in
the public domain.  Import was performed using:
  % tools/provisiontool mbpi-convert --outfile=provision.json
---
 provision.json | 15022 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 15022 insertions(+)
 create mode 100644 provision.json

diff --git a/provision.json b/provision.json
new file mode 100644
index 00000000..c52d5752
--- /dev/null
+++ b/provision.json
@@ -0,0 +1,15022 @@
+[
+  {
+    "name": "Andorra Telecom (Mobiland)",
+    "ids": [
+      "21303"
+    ],
+    "apns": [
+      {
+        "name": "Mobiland",
+        "apn": "internetand",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Mobiland Click!",
+        "apn": "internetclic",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Andorra Telecom MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.ad/mmsc",
+        "mmsproxy": "192.168.21.50:8080"
+      }
+    ]
+  },
+  {
+    "name": "Etisalat",
+    "ids": [
+      "42402"
+    ],
+    "apns": [
+      {
+        "name": "Etisalat",
+        "apn": "mnet",
+        "type": [
+          "internet"
+        ],
+        "username": "mnet",
+        "password": "mnet"
+      },
+      {
+        "name": "Etisalat 3G",
+        "apn": "etisalat.ae",
+        "type": [
+          "internet"
+        ],
+        "username": "etisalat.ae",
+        "password": "etisalat.ae"
+      },
+      {
+        "name": "etisalat MMS",
+        "apn": "etisalat",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.99.52.150/servlets/mms",
+        "mmsproxy": "10.12.0.30:8080"
+      },
+      {
+        "name": "etisalat MMS",
+        "apn": "etisalat",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms/servlets/mms",
+        "mmsproxy": "10.12.0.32:8080"
+      }
+    ]
+  },
+  {
+    "name": "du",
+    "ids": [
+      "42403"
+    ],
+    "apns": [
+      {
+        "apn": "du",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "du MMS",
+        "apn": "du",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.du.ae",
+        "mmsproxy": "10.19.18.4:8080"
+      }
+    ]
+  },
+  {
+    "name": "AWCC",
+    "ids": [
+      "41201"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "awcc",
+        "password": "1111"
+      },
+      {
+        "name": "AWCC MMS",
+        "apn": "mms1",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://172.17.81.2:8002",
+        "mmsproxy": "172.17.81.2:8002"
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "27602"
+    ],
+    "apns": [
+      {
+        "name": "TWA",
+        "apn": "Twa",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Vodafone Web",
+        "apn": "vodafoneweb",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Vodafone MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://217.31.233.18:6001/MM1Servlet",
+        "mmsproxy": "217.31.233.18:9401",
+        "username": "vodafone",
+        "password": "vodafone"
+      },
+      {
+        "name": "Vodafone MMS",
+        "apn": "portalnmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms1.live.vodafone.in/mms/",
+        "mmsproxy": "10.10.1.100:9401"
+      }
+    ]
+  },
+  {
+    "name": "Albania Mobile Communications (AMC)",
+    "ids": [
+      "27601"
+    ],
+    "apns": [
+      {
+        "name": "AMC internet",
+        "apn": "Internet",
+        "type": [
+          "internet"
+        ],
+        "username": "internet"
+      }
+    ]
+  },
+  {
+    "name": "Beeline",
+    "ids": [
+      "28301"
+    ],
+    "apns": [
+      {
+        "apn": "internet.beeline.am",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      },
+      {
+        "name": "Beeline MMS",
+        "apn": "mms.beeline.ua",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms/",
+        "mmsproxy": "10.11.8.18:8080"
+      },
+      {
+        "name": "Beeline MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms",
+        "mmsproxy": "10.16.70.199:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "28310"
+    ],
+    "apns": [
+      {
+        "name": "Internet Hima (USB)",
+        "apn": "internet.orange",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Mobile Broadband",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Orange MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.orange.nl:8002",
+        "mmsproxy": "10.250.255.183:5080"
+      },
+      {
+        "name": "Orange MMS",
+        "apn": "orangemms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.orange.es",
+        "mmsproxy": "wapmms.orange.es:8080",
+        "username": "orange",
+        "password": "orange"
+      },
+      {
+        "name": "Orange MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://192.168.151.3:8002",
+        "mmsproxy": "192.168.151.2:8080"
+      },
+      {
+        "name": "Orange MMS",
+        "apn": "orange.mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.orange.at/mms/wapenc",
+        "mmsproxy": "194.24.128.118:8080",
+        "username": "mms",
+        "password": "mms"
+      },
+      {
+        "name": "Orange MMS",
+        "apn": "orangemms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.orange.co.uk/",
+        "mmsproxy": "192.168.224.10:8080"
+      },
+      {
+        "name": "Orange MMS",
+        "apn": "mms.orange.dk",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.orange.dk:8002",
+        "mmsproxy": "172.18.251.11:8080"
+      },
+      {
+        "name": "Orange MMS",
+        "apn": "mms.orange.md",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms/mms",
+        "mmsproxy": "192.168.127.125:3128"
+      },
+      {
+        "name": "Orange MMS",
+        "apn": "mms.orange.jo",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://172.16.1.96/servlets/mms",
+        "mmsproxy": "172.16.1.2:8080",
+        "username": "mmc",
+        "password": "mmc"
+      },
+      {
+        "name": "Orange MMS",
+        "apn": "orangerun.acte",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.orange.re",
+        "mmsproxy": "192.168.10.200:8080"
+      }
+    ]
+  },
+  {
+    "name": "VivaCell/MTS",
+    "ids": [
+      "28305"
+    ],
+    "apns": [
+      {
+        "name": "MTS connect",
+        "apn": "connect.vivacell.am",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Mobile Broadband",
+        "apn": "inet.vivacell.am",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Karabakh Telecom",
+    "ids": [
+      "28304"
+    ],
+    "apns": [
+      {
+        "name": "KT_MARK",
+        "apn": "connect.kt.am",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Unitel",
+    "ids": [
+      "63102"
+    ],
+    "apns": [
+      {
+        "apn": "internet.unitel.co.ao",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "unitel mms",
+        "apn": "unitel",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http//mms.unitel.com"
+      }
+    ]
+  },
+  {
+    "name": "Personal",
+    "ids": [
+      "72234",
+      "722341"
+    ],
+    "apns": [
+      {
+        "name": "GPRS",
+        "apn": "gprs.personal.com",
+        "type": [
+          "internet"
+        ],
+        "username": "gprs",
+        "password": "adgj"
+      },
+      {
+        "name": "DATOS",
+        "apn": "datos.personal.com",
+        "type": [
+          "internet"
+        ],
+        "username": "datos",
+        "password": "datos"
+      }
+    ]
+  },
+  {
+    "name": "Arnet",
+    "ids": [
+      "722340"
+    ],
+    "apns": [
+      {
+        "apn": "arnet.personal.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Personal MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.personal.com/",
+        "mmsproxy": "172.25.7.31:8080",
+        "username": "mms",
+        "password": "mms"
+      },
+      {
+        "name": "MMS Personal",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms",
+        "mmsproxy": "172.16.192.7:8080"
+      }
+    ]
+  },
+  {
+    "name": "Claro",
+    "ids": [
+      "722310",
+      "722320",
+      "722330"
+    ],
+    "apns": [
+      {
+        "name": "3G Internet",
+        "apn": "gprs.claro.com.ar",
+        "type": [
+          "internet"
+        ],
+        "username": "clarogprs",
+        "password": "clarogprs999"
+      },
+      {
+        "name": "GPRS",
+        "apn": "internet.ctimovil.com.ar",
+        "type": [
+          "internet"
+        ],
+        "username": "clarogprs",
+        "password": "clarogprs999"
+      },
+      {
+        "name": "Claro Foto",
+        "apn": "mms.claro.com.br",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.claro.com.br/",
+        "mmsproxy": "200.169.126.10:8799",
+        "username": "claro",
+        "password": "claro"
+      }
+    ]
+  },
+  {
+    "name": "Movistar",
+    "ids": [
+      "722010",
+      "722070"
+    ],
+    "apns": [
+      {
+        "name": "WAP",
+        "apn": "internet.gprs.unifon.com.ar",
+        "type": [
+          "internet"
+        ],
+        "username": "wap",
+        "password": "wap"
+      },
+      {
+        "name": "Internet",
+        "apn": "internet.gprs.unifon.com.ar",
+        "type": [
+          "internet"
+        ],
+        "username": "Internet",
+        "password": "Internet"
+      }
+    ]
+  },
+  {
+    "name": "A1/Telekom Austria",
+    "ids": [
+      "23201"
+    ],
+    "apns": [
+      {
+        "name": "A1 Breitband",
+        "apn": "a1.net",
+        "type": [
+          "internet"
+        ],
+        "username": "ppp@a1plus.at",
+        "password": "ppp"
+      },
+      {
+        "name": "aon (Flex, Breitband-Duo, BusinessFlex)",
+        "apn": "aon.data",
+        "type": [
+          "internet"
+        ],
+        "username": "mobile@aon.at",
+        "password": "ppp"
+      },
+      {
+        "name": "aonMobile",
+        "apn": "aon.at",
+        "type": [
+          "internet"
+        ],
+        "username": "mobile@aon.at",
+        "password": "ppp"
+      },
+      {
+        "name": "A1MMS",
+        "apn": "free.A1.net",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.A1.net",
+        "mmsproxy": "gateway.A1.net:8001",
+        "username": "ppp@A1plus.at",
+        "password": "ppp"
+      }
+    ]
+  },
+  {
+    "name": "ABroadband",
+    "ids": [
+      "23201"
+    ],
+    "apns": [
+      {
+        "name": "International Roaming",
+        "apn": "mdata.com",
+        "type": [
+          "internet"
+        ],
+        "username": "mdata@mdata.com",
+        "password": "ppp"
+      }
+    ]
+  },
+  {
+    "name": "Bob",
+    "ids": [
+      "23211"
+    ],
+    "apns": [
+      {
+        "apn": "bob.at",
+        "type": [
+          "internet"
+        ],
+        "username": "data@bob.at",
+        "password": "ppp"
+      },
+      {
+        "apn": "bob.at",
+        "type": [
+          "internet"
+        ],
+        "username": "ppp@bob.at",
+        "password": "ppp"
+      },
+      {
+        "apn": "mms.bob.at",
+        "type": [
+          "internet"
+        ],
+        "username": "data@bob.at",
+        "password": "ppp"
+      },
+      {
+        "name": "data bob MMS",
+        "apn": "mms.bob.at",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.bob.at",
+        "mmsproxy": "194.48.124.7:8001",
+        "username": "data@bob.at",
+        "password": "ppp"
+      }
+    ]
+  },
+  {
+    "name": "HoT",
+    "ids": [
+      "23207"
+    ],
+    "apns": [
+      {
+        "apn": "webaut",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "HoT MMS",
+        "apn": "mmsaut",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsaut.at/send",
+        "mmsproxy": "212.95.31.50:80"
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "23208"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.at",
+        "type": [
+          "internet"
+        ],
+        "username": "lmat",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "T-Mobile",
+    "ids": [
+      "23203"
+    ],
+    "apns": [
+      {
+        "name": "WAP",
+        "apn": "gprswap",
+        "type": [
+          "wap"
+        ],
+        "username": "t-mobile",
+        "password": "tm"
+      },
+      {
+        "name": "Internet",
+        "apn": "gprsinternet",
+        "type": [
+          "internet"
+        ],
+        "username": "t-mobile",
+        "password": "tm"
+      },
+      {
+        "name": "Business Internet",
+        "apn": "business.gprsinternet",
+        "type": [
+          "internet"
+        ],
+        "username": "t-mobile",
+        "password": "tm"
+      },
+      {
+        "name": "T-Mobile MMS",
+        "apn": "general.t-mobile.uk",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.t-mobile.co.uk:8002",
+        "mmsproxy": "149.254.201.135:8080",
+        "username": "user",
+        "password": "wap"
+      },
+      {
+        "name": "MMS",
+        "apn": "wap.voicestream.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://216.155.174.84/servlets/mms",
+        "mmsproxy": "216.155.165.50:8080",
+        "username": "nokia",
+        "password": "6600"
+      }
+    ]
+  },
+  {
+    "name": "tele.ring",
+    "ids": [
+      "23207"
+    ],
+    "apns": [
+      {
+        "name": "Ge org:)",
+        "apn": "web",
+        "type": [
+          "internet"
+        ],
+        "username": "web@telering.at",
+        "password": "web"
+      },
+      {
+        "name": "tele ring mms",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://relay.mms.telering.at",
+        "mmsproxy": "212.95.31.50:8080",
+        "username": "wap@telering.at",
+        "password": "wap"
+      }
+    ]
+  },
+  {
+    "name": "Drei (3)",
+    "ids": [
+      "23205",
+      "23210"
+    ],
+    "apns": [
+      {
+        "apn": "drei.at",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "3MMS",
+        "apn": "drei.at",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc",
+        "mmsproxy": "213.94.78.133:8799"
+      },
+      {
+        "name": "3 MMS",
+        "apn": "three.co.uk",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.um.three.co.uk:10021/mmsc",
+        "mmsproxy": "mms.three.co.uk:8799"
+      },
+      {
+        "name": "3MMS",
+        "apn": "mobile.three.com.hk",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.um.three.com.hk:10021/mmsc",
+        "mmsproxy": "172.20.97.116:8799"
+      },
+      {
+        "name": "3 MMS",
+        "apn": "3services",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.three.net.au:10021/mmsc",
+        "mmsproxy": "mmscprox.three.net.au:8799"
+      },
+      {
+        "name": "3mms",
+        "apn": "3mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.three.co.id",
+        "mmsproxy": "10.4.0.10:3128",
+        "username": "3mms",
+        "password": "3mms"
+      }
+    ]
+  },
+  {
+    "name": "Yesss",
+    "ids": [
+      "23212"
+    ],
+    "apns": [
+      {
+        "apn": "web.yesss.at",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "VOLmobil",
+    "ids": [
+      "23203"
+    ],
+    "apns": [
+      {
+        "apn": "volmobil",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "T-Mobile MMS",
+        "apn": "gprsmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.t-mobile.at/servlets/mms",
+        "mmsproxy": "10.12.0.20:80",
+        "username": "t-mobile",
+        "password": "tm"
+      }
+    ]
+  },
+  {
+    "name": "Aldi Mobile AU",
+    "ids": [
+      "50501"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Data",
+        "apn": "mdata.net.au",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.mdata.net.au:8003",
+        "mmsproxy": "10.1.1.180"
+      }
+    ]
+  },
+  {
+    "name": "Amaysim",
+    "ids": [
+      "50502"
+    ],
+    "apns": [
+      {
+        "name": "Optus MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.optus.com.au:8002/",
+        "mmsproxy": "61.88.190.10:8070"
+      }
+    ]
+  },
+  {
+    "name": "Crazy John's",
+    "ids": [
+      "50503",
+      "50538"
+    ],
+    "apns": [
+      {
+        "name": "Crazy NET",
+        "apn": "purtona.net",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Crazy WAP/MMS",
+        "apn": "purtona.wap",
+        "type": [
+          "wap"
+        ]
+      },
+      {
+        "name": "Crazy MMS",
+        "apn": "purtona.wap",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://purtona.mms/mmssend",
+        "mmsproxy": "10.202.2.20:8080"
+      }
+    ]
+  },
+  {
+    "name": "iiNet",
+    "ids": [
+      "50502"
+    ],
+    "apns": [
+      {
+        "apn": "iinet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Internode",
+    "ids": [
+      "50502"
+    ],
+    "apns": [
+      {
+        "name": "NodeMobile Data",
+        "apn": "internode",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Old NodeMobile Data (before 2009-08-26)",
+        "apn": "splns333a1",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "50519"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.com.au",
+        "type": [
+          "internet"
+        ],
+        "username": "lmau",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "Optus",
+    "ids": [
+      "50502"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Internet (handsets)",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Optus Yes Internet",
+        "apn": "yesinternet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Wireless Broadband",
+        "apn": "connect",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Post-Paid Mobile Broadband",
+        "apn": "connectcap",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Pre-Paid Mobile Broadband",
+        "apn": "preconnect",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "TPG Mobile",
+    "ids": [
+      "50502"
+    ],
+    "apns": [
+      {
+        "name": "TPG (all except iPhone)",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Telstra",
+    "ids": [
+      "50501"
+    ],
+    "apns": [
+      {
+        "apn": "telstra.wap",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Telstra (3G data pack)",
+        "apn": "telstra.datapack",
+        "type": [
+          "internet"
+        ],
+        "password": "Telstra"
+      },
+      {
+        "name": "Telstra (Next G)",
+        "apn": "telstra.internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Telstra (3G PC pack - pay by time)",
+        "apn": "telstra.pcpack",
+        "type": [
+          "internet"
+        ],
+        "password": "Telstra"
+      },
+      {
+        "name": "Telstra Internet/Wap",
+        "apn": "telstra.iph",
+        "type": [
+          "wap"
+        ]
+      },
+      {
+        "name": "Telstra BigPond",
+        "apn": "telstra.bigpond",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Telstra MMS",
+        "apn": "telstra.mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.telstra.com:8002",
+        "mmsproxy": "10.1.1.180:80"
+      }
+    ]
+  },
+  {
+    "name": "Three",
+    "ids": [
+      "50506"
+    ],
+    "apns": [
+      {
+        "apn": "3netaccess",
+        "type": [
+          "internet"
+        ],
+        "username": "a",
+        "password": "a"
+      },
+      {
+        "name": "Three Prepaid",
+        "apn": "3services",
+        "type": [
+          "internet"
+        ],
+        "username": "a",
+        "password": "a"
+      }
+    ]
+  },
+  {
+    "name": "Virgin Mobile",
+    "ids": [
+      "50502"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Internet",
+        "apn": "VirginInternet",
+        "type": [
+          "internet"
+        ],
+        "username": "guest",
+        "password": "guest"
+      },
+      {
+        "name": "Mobile Broadband",
+        "apn": "VirginBroadband",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "50503"
+    ],
+    "apns": [
+      {
+        "name": "Postpaid and some prepaid phone plans",
+        "apn": "vfinternet.au",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Prepaid",
+        "apn": "vfprepaymbb",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Vodafone Internet",
+        "apn": "live.vodafone.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Azercell",
+    "ids": [
+      "40001"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Azercell MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.azercell.com/cMMSC/post",
+        "mmsproxy": "10.0.154.101:8080"
+      }
+    ]
+  },
+  {
+    "name": "Bakcell",
+    "ids": [
+      "40002"
+    ],
+    "apns": [
+      {
+        "apn": "mms",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Azerfon",
+    "ids": [
+      "40004"
+    ],
+    "apns": [
+      {
+        "apn": "azerfon",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "BH GSM",
+    "ids": [
+      "21890"
+    ],
+    "apns": [
+      {
+        "name": "BHMobileMMS",
+        "apn": "mms.bhmobile.ba",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.bhmobile.ba/cmmsc/post",
+        "mmsproxy": "195.222.56.41:8080"
+      }
+    ]
+  },
+  {
+    "name": "m:tel",
+    "ids": [
+      "21805"
+    ],
+    "apns": [
+      {
+        "name": "Package 1",
+        "apn": "mtelgprs1",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Package 2",
+        "apn": "mtelgprs2",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Package 3",
+        "apn": "mtelgprs3",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Package 4",
+        "apn": "mtelgprs4",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Prepaid",
+        "apn": "mtelfun",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "mobismms",
+        "apn": "mobismms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.065mobis.com/mms/wapenc",
+        "mmsproxy": "192.168.61.11:80"
+      }
+    ]
+  },
+  {
+    "name": "HT-ERONET",
+    "ids": [
+      "21803"
+    ],
+    "apns": [
+      {
+        "apn": "gprs.eronet.ba",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "ERONET MMS",
+        "apn": "mms.eronet.ba",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.gprs.eronet.ba/mms/wapenc",
+        "mmsproxy": "10.12.3.11:8080"
+      }
+    ]
+  },
+  {
+    "name": "Digicel",
+    "ids": [
+      "342750"
+    ],
+    "apns": [
+      {
+        "apn": "isp.digicelbarbados.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Robi (AKTel)",
+    "ids": [
+      "47002"
+    ],
+    "apns": [
+      {
+        "name": "Robi Internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Robi Internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Robi MMS",
+        "apn": "wap",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://192.168.23.4/was",
+        "mmsproxy": "192.168.23.7:9028"
+      }
+    ]
+  },
+  {
+    "name": "Banglalink",
+    "ids": [
+      "47003"
+    ],
+    "apns": [
+      {
+        "name": "Banglalink Web",
+        "apn": "blweb",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Banglalink Web",
+        "apn": "blweb",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Banglalink MMS",
+        "apn": "blmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc1:10021/mmsc/01",
+        "mmsproxy": "10.10.55.34:8799"
+      }
+    ]
+  },
+  {
+    "name": "GrameenPhone",
+    "ids": [
+      "47001"
+    ],
+    "apns": [
+      {
+        "name": "GP Internet",
+        "apn": "gpinternet",
+        "type": [
+          "internet"
+        ],
+        "username": "gp",
+        "password": "gp"
+      },
+      {
+        "name": "GP Internet",
+        "apn": "gpinternet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "GP MMS",
+        "apn": "gpmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.gpsurf.net/servlets/mms",
+        "mmsproxy": "10.128.1.2:8080"
+      }
+    ]
+  },
+  {
+    "name": "Airtel (Warid)",
+    "ids": [
+      "47007"
+    ],
+    "apns": [
+      {
+        "name": "Airtel Internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Airtel Internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Airtel MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.6.0.21/servlets/mms",
+        "mmsproxy": "10.6.0.2:8080"
+      }
+    ]
+  },
+  {
+    "name": "Teletalk",
+    "ids": [
+      "47004"
+    ],
+    "apns": [
+      {
+        "name": "Teletalk Internet",
+        "apn": "wap",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Teletalk MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.5.4.22:38090/was",
+        "mmsproxy": "10.5.4.40:8080"
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "20606"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.be",
+        "type": [
+          "internet"
+        ],
+        "username": "lmbe",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "Mobistar",
+    "ids": [
+      "20610"
+    ],
+    "apns": [
+      {
+        "name": "Business",
+        "apn": "web.pro.be",
+        "type": [
+          "internet"
+        ],
+        "username": "mobistar",
+        "password": "mobistar"
+      },
+      {
+        "name": "Personal",
+        "apn": "internet.be",
+        "type": [
+          "internet"
+        ],
+        "username": "mobistar",
+        "password": "mobistar"
+      },
+      {
+        "name": "Internet Everywhere",
+        "apn": "iew.be",
+        "type": [
+          "internet"
+        ],
+        "username": "mobistar",
+        "password": "mobistar"
+      },
+      {
+        "apn": "mworld.be",
+        "type": [
+          "internet"
+        ],
+        "username": "mobistar",
+        "password": "mobistar"
+      },
+      {
+        "name": "Mobistar MMS",
+        "apn": "mms.be",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.mobistar.be",
+        "mmsproxy": "212.65.63.143:8080"
+      }
+    ]
+  },
+  {
+    "name": "Telenet Mobile",
+    "ids": [
+      "20610"
+    ],
+    "apns": [
+      {
+        "name": "Old Walk & Surf",
+        "apn": "mobile.internet.be",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Walk & Talk",
+        "apn": "telenetwap.be",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Walk & Surf",
+        "apn": "telenetwap.be",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "20610"
+    ],
+    "apns": [
+      {
+        "apn": "orangeinternet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Proximus",
+    "ids": [
+      "20601"
+    ],
+    "apns": [
+      {
+        "name": "Inter",
+        "apn": "internet.proximus.be",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Intra",
+        "apn": "intraprox.be",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "event.proximus.be",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.proximus.be/mms",
+        "mmsproxy": "10.55.14.75:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Base",
+    "ids": [
+      "20620"
+    ],
+    "apns": [
+      {
+        "apn": "gprs.base.be",
+        "type": [
+          "internet"
+        ],
+        "username": "base",
+        "password": "base"
+      },
+      {
+        "name": "BASE MMS",
+        "apn": "mms.base.be",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.base.be",
+        "mmsproxy": "217.72.235.1:8080",
+        "username": "base",
+        "password": "base"
+      }
+    ]
+  },
+  {
+    "name": "Mobile Vikings",
+    "ids": [
+      "20620"
+    ],
+    "apns": [
+      {
+        "apn": "web.be",
+        "type": [
+          "internet"
+        ],
+        "username": "web",
+        "password": "web"
+      }
+    ]
+  },
+  {
+    "name": "Airtel 3G",
+    "ids": [
+      "61302"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "GloBul",
+    "ids": [
+      "28405"
+    ],
+    "apns": [
+      {
+        "apn": "internet.globul.bg",
+        "type": [
+          "internet"
+        ],
+        "username": "globul"
+      },
+      {
+        "name": "GLOBUL MMS GPRS",
+        "apn": "mms.globul.bg",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc1.mms.globul.bg:8002",
+        "mmsproxy": "192.168.87.11:8004",
+        "username": "mms"
+      }
+    ]
+  },
+  {
+    "name": "M-Tel",
+    "ids": [
+      "28401"
+    ],
+    "apns": [
+      {
+        "apn": "inet-gprs.mtel.bg",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS M-Tel GPRS",
+        "apn": "mms-gprs.mtel.bg",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc/",
+        "mmsproxy": "10.150.0.33:8080",
+        "username": "mtel",
+        "password": "mtel"
+      }
+    ]
+  },
+  {
+    "name": "Vivacom",
+    "ids": [
+      "28403"
+    ],
+    "apns": [
+      {
+        "name": "Vivacom Internet (Postpaid)",
+        "apn": "internet.vivacom.bg",
+        "type": [
+          "internet"
+        ],
+        "username": "vivacom",
+        "password": "vivacom"
+      },
+      {
+        "name": "Vivatel (old)",
+        "apn": "internet.vivatel.bg",
+        "type": [
+          "internet"
+        ],
+        "username": "vivatel",
+        "password": "vivatel"
+      },
+      {
+        "name": "vivacom MMS",
+        "apn": "mms.vivacom.bg",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.vivacom.bg",
+        "mmsproxy": "192.168.123.123:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Batelco",
+    "ids": [
+      "42601"
+    ],
+    "apns": [
+      {
+        "name": "oNet",
+        "apn": "internet.batelco.com",
+        "type": [
+          "internet"
+        ],
+        "username": "wap",
+        "password": "wap"
+      },
+      {
+        "name": "Batelco MMS",
+        "apn": "mms.batelco.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://192.168.36.10/servlets/mms",
+        "mmsproxy": "192.168.1.2:80",
+        "username": "wap",
+        "password": "wap"
+      }
+    ]
+  },
+  {
+    "name": "Zain BH",
+    "ids": [
+      "42602"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      },
+      {
+        "name": "eGO",
+        "apn": "hsdpa",
+        "type": [
+          "internet"
+        ],
+        "username": "hsdpa",
+        "password": "hsdpa"
+      },
+      {
+        "name": "mms",
+        "apn": "http://172.18.83.129",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://172.18.83.129",
+        "mmsproxy": "172.18.85.34:80",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "STC",
+    "ids": [
+      "42604"
+    ],
+    "apns": [
+      {
+        "name": "Viva",
+        "apn": "viva.bh",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Brasil Telecom",
+    "ids": [
+      "72416"
+    ],
+    "apns": [
+      {
+        "apn": "brt.br",
+        "type": [
+          "internet"
+        ],
+        "username": "BrT",
+        "password": "BrT"
+      },
+      {
+        "name": "BrT MMS",
+        "apn": "mms.brt.br",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.brasiltelecom.com.br/",
+        "mmsproxy": "200.96.8.29:8080",
+        "username": "brt",
+        "password": "brt"
+      }
+    ]
+  },
+  {
+    "name": "Claro",
+    "ids": [
+      "72405"
+    ],
+    "apns": [
+      {
+        "apn": "claro.com.br",
+        "type": [
+          "internet"
+        ],
+        "username": "claro",
+        "password": "claro"
+      },
+      {
+        "name": "3G",
+        "apn": "bandalarga.claro.com.br",
+        "type": [
+          "internet"
+        ],
+        "username": "claro",
+        "password": "claro"
+      }
+    ]
+  },
+  {
+    "name": "CTBC",
+    "ids": [
+      "72407",
+      "72432",
+      "72433",
+      "72434"
+    ],
+    "apns": [
+      {
+        "apn": "ctbc.br",
+        "type": [
+          "internet"
+        ],
+        "username": "ctbc",
+        "password": "1212"
+      },
+      {
+        "name": "CTBC MMS",
+        "apn": "mms.ctbc.br",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.ctbccelular.com.br/was",
+        "mmsproxy": "172.29.7.70:8080",
+        "username": "ctbc",
+        "password": "1212"
+      }
+    ]
+  },
+  {
+    "name": "Oi",
+    "ids": [
+      "72416",
+      "72424",
+      "72431"
+    ],
+    "apns": [
+      {
+        "apn": "gprs.oi.com.br",
+        "type": [
+          "internet"
+        ],
+        "password": "oioioi"
+      },
+      {
+        "name": "WAP",
+        "apn": "wapgprs.oi.com.br",
+        "type": [
+          "wap"
+        ],
+        "username": "oiwap",
+        "password": "oioioi"
+      },
+      {
+        "name": "Oi MMS",
+        "apn": "mmsgprs.oi.com.br",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://200.222.42.204:8002",
+        "mmsproxy": "192.168.10.50:3128",
+        "username": "oimms",
+        "password": "oioioi"
+      }
+    ]
+  },
+  {
+    "name": "TIM",
+    "ids": [
+      "72402",
+      "72403",
+      "72404",
+      "72408"
+    ],
+    "apns": [
+      {
+        "apn": "tim.br",
+        "type": [
+          "internet"
+        ],
+        "username": "tim",
+        "password": "tim"
+      },
+      {
+        "name": "iTIM",
+        "apn": "unico.tim.it",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.tim.it/servlets/mms",
+        "mmsproxy": "213.230.130.89:80"
+      },
+      {
+        "name": "TIM MMS",
+        "apn": "timbrasil.br",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.tim.br",
+        "mmsproxy": "200.179.66.242:8080",
+        "username": "tim",
+        "password": "tim"
+      }
+    ]
+  },
+  {
+    "name": "Vivo",
+    "ids": [
+      "72406",
+      "72410",
+      "72411",
+      "72423"
+    ],
+    "apns": [
+      {
+        "apn": "zap.vivo.com.br",
+        "type": [
+          "internet"
+        ],
+        "username": "vivo",
+        "password": "vivo"
+      },
+      {
+        "name": "Vivo MMS",
+        "apn": "mms.vivo.com.br",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://termnat.vivomms.com.br:8088/mms",
+        "mmsproxy": "200.142.130.104:80",
+        "username": "vivo",
+        "password": "vivo"
+      }
+    ]
+  },
+  {
+    "name": "Aliv",
+    "ids": [
+      "36449"
+    ],
+    "apns": [
+      {
+        "apn": "pda.newcomobile.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Batelco",
+    "ids": [
+      "364390"
+    ],
+    "apns": [
+      {
+        "apn": "internet.btcbahamas.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "B-Mobile",
+    "ids": [
+      "52802"
+    ],
+    "apns": [
+      {
+        "apn": "bmobilewap",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "B-mobile MMS",
+        "apn": "bmobilemms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.bmobile.com.bn/was",
+        "mmsproxy": "129.9.10.20:6500"
+      }
+    ]
+  },
+  {
+    "name": "DSTCOM",
+    "ids": [
+      "52811"
+    ],
+    "apns": [
+      {
+        "apn": "dst.wap",
+        "type": [
+          "internet"
+        ],
+        "username": "wap",
+        "password": "wap"
+      },
+      {
+        "name": "Movistar MMS",
+        "apn": "mms.movistar.es",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.movistar.com",
+        "mmsproxy": "10.138.255.5:8080",
+        "username": "MOVISTAR@mms",
+        "password": "MOVISTAR"
+      }
+    ]
+  },
+  {
+    "name": "velcom",
+    "ids": [
+      "25701"
+    ],
+    "apns": [
+      {
+        "name": "GPRS WAP",
+        "apn": "wap.velcom.by",
+        "type": [
+          "wap"
+        ],
+        "username": "wap",
+        "password": "wap"
+      },
+      {
+        "name": "GPRS WEB",
+        "apn": "web.velcom.by",
+        "type": [
+          "internet"
+        ],
+        "username": "web",
+        "password": "web"
+      },
+      {
+        "name": "GPRS WEB PLUS",
+        "apn": "plus.velcom.by",
+        "type": [
+          "internet"
+        ],
+        "username": "plus",
+        "password": "plus"
+      },
+      {
+        "name": "GPRS PRIVET",
+        "apn": "privet.velcom.by",
+        "type": [
+          "internet"
+        ],
+        "username": "privet",
+        "password": "privet"
+      },
+      {
+        "name": "WEB BASIC",
+        "apn": "web1.velcom.by",
+        "type": [
+          "internet"
+        ],
+        "username": "web1",
+        "password": "web1"
+      },
+      {
+        "name": "WEB 25",
+        "apn": "web2.velcom.by",
+        "type": [
+          "internet"
+        ],
+        "username": "web2",
+        "password": "web2"
+      },
+      {
+        "name": "WEB 150",
+        "apn": "web3.velcom.by",
+        "type": [
+          "internet"
+        ],
+        "username": "web3",
+        "password": "web3"
+      },
+      {
+        "name": "WEB 500",
+        "apn": "vmi.velcom.by",
+        "type": [
+          "internet"
+        ],
+        "username": "vmi",
+        "password": "vmi"
+      },
+      {
+        "name": "VELCOM MMS",
+        "apn": "mms.velcom.by",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.velcom.by/servlets/mms",
+        "mmsproxy": "10.200.15.15:8080"
+      }
+    ]
+  },
+  {
+    "name": "MTS",
+    "ids": [
+      "25702"
+    ],
+    "apns": [
+      {
+        "apn": "internet.mts.by",
+        "type": [
+          "internet"
+        ],
+        "username": "mts",
+        "password": "mts"
+      },
+      {
+        "name": "MTS MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.mts064.telekom.yu/mms/wapenc",
+        "mmsproxy": "172.17.85.131:8080"
+      },
+      {
+        "name": "MTS MMS",
+        "apn": "mms.mts.ru",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc/",
+        "mmsproxy": "192.168.192.192:9201",
+        "username": "mts",
+        "password": "mts"
+      },
+      {
+        "name": "UMC MMS GPRS",
+        "apn": "mms.umc.ua",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc:8002/",
+        "mmsproxy": "192.168.10.10:8080"
+      },
+      {
+        "name": "MTS MMS",
+        "apn": "sp.mts",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc2.mts.net",
+        "mmsproxy": "209.4.229.90:9401"
+      }
+    ]
+  },
+  {
+    "name": "life:)",
+    "ids": [
+      "25704"
+    ],
+    "apns": [
+      {
+        "apn": "internet.life.com.by",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Mascom Wireless",
+    "ids": [
+      "65201"
+    ],
+    "apns": [
+      {
+        "apn": "internet.mascom",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "life:) MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.life.com.ua/cmmsc/post",
+        "mmsproxy": "212.58.162.230:8080"
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "65202"
+    ],
+    "apns": [
+      {
+        "apn": "internet.orange.co.bw",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Leo/UCom",
+    "ids": [
+      "64203"
+    ],
+    "apns": [
+      {
+        "apn": "ucnet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Tempo/Africell",
+    "ids": [
+      "64202"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Mascom MMS",
+        "apn": "mms.mascom",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://192.168.33.50/mms",
+        "mmsproxy": "192.168.33.138:8080"
+      }
+    ]
+  },
+  {
+    "name": "Fido",
+    "ids": [
+      "302370"
+    ],
+    "apns": [
+      {
+        "apn": "ltemobile.apn",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Fido MMS",
+        "apn": "mms.fido.ca",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.fido.ca",
+        "mmsproxy": "mm1.fido.ca:80"
+      }
+    ]
+  },
+  {
+    "name": "Rogers",
+    "ids": [
+      "302720"
+    ],
+    "apns": [
+      {
+        "apn": "internet.com",
+        "type": [
+          "internet"
+        ],
+        "username": "wapuser1",
+        "password": "wap"
+      },
+      {
+        "name": "Rogers Internet",
+        "apn": "ltemobile.apn",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Rogers Tethering",
+        "apn": "ltedata.apn",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Rogers Media",
+        "apn": "media.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.gprs.rogers.com",
+        "mmsproxy": "10.128.1.69:80",
+        "username": "media",
+        "password": "mda01"
+      }
+    ]
+  },
+  {
+    "name": "Bell Mobility",
+    "ids": [
+      "302610",
+      "302640",
+      "302651",
+      "302880"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "inet.bell.ca",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Mobile Web",
+        "apn": "pda.bell.ca",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Mobile Fast Web",
+        "apn": "pda2.bell.ca",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Bell MMS",
+        "apn": "pda.bell.ca",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.bell.ca/mms/wapenc",
+        "mmsproxy": "web.wireless.bell.ca:80"
+      }
+    ]
+  },
+  {
+    "name": "Telus Mobility",
+    "ids": [
+      "302220",
+      "302860",
+      "302880"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "isp.telus.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Internet (with VPN)",
+        "apn": "vpn.telus.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Blackberry",
+        "apn": "bb.telus.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Mobile Web/Smartphone",
+        "apn": "sp.telus.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "TELUS MMS",
+        "apn": "sp.telus.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://aliasredirect.net/proxy/mmsc",
+        "mmsproxy": "74.49.0.18:80"
+      }
+    ]
+  },
+  {
+    "name": "SaskTel Mobility",
+    "ids": [
+      "302680",
+      "302750",
+      "302780",
+      "302880"
+    ],
+    "apns": [
+      {
+        "name": "Data Device or Tethering",
+        "apn": "inet.stm.sk.ca",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Vidéotron",
+    "ids": [
+      "302500",
+      "302510"
+    ],
+    "apns": [
+      {
+        "name": "Telephony data",
+        "apn": "media.videotron",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "IHVM",
+        "apn": "ihvm.videotron",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Media",
+        "apn": "media.videotron",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://media.videotron.com",
+        "mmsproxy": "10.208.89.17:8080"
+      }
+    ]
+  },
+  {
+    "name": "Freedom Mobile",
+    "ids": [
+      "302490"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "internet.freedommobile.ca",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "mms.freedommobile.ca",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.freedommobile.ca",
+        "mmsproxy": "74.115.197.70:8080"
+      }
+    ]
+  },
+  {
+    "name": "Mobilicity",
+    "ids": [
+      "302320"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Web",
+        "apn": "wap.davewireless.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Mobile Broadband",
+        "apn": "internet.davewireless.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MoMMS",
+        "apn": "mms.davewireless.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.mobilicity.net",
+        "mmsproxy": "10.100.3.4:8080"
+      }
+    ]
+  },
+  {
+    "name": "Public Mobile",
+    "ids": [
+      "302220"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "sp.mb.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Public Mobile MMS",
+        "apn": "sp.mb.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://aliasredirect.net/proxy/mb/mmsc",
+        "mmsproxy": "74.49.0.18:80"
+      }
+    ]
+  },
+  {
+    "name": "Vodacom",
+    "ids": [
+      "63001"
+    ],
+    "apns": [
+      {
+        "apn": "vodanet",
+        "type": [
+          "internet"
+        ],
+        "username": "vodalive"
+      },
+      {
+        "name": "Vodalive",
+        "apn": "vodalive",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://172.24.97.1/mmsc",
+        "mmsproxy": "172.24.97.1:3128"
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "22854"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.ch",
+        "type": [
+          "internet"
+        ],
+        "username": "lmch",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "Salt",
+    "ids": [
+      "22803"
+    ],
+    "apns": [
+      {
+        "name": "Salt World - Prepaid",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Salt Internet - Postpaid",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Salt MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://192.168.151.3:8002",
+        "mmsproxy": "192.168.151.2:8080"
+      }
+    ]
+  },
+  {
+    "name": "Sunrise",
+    "ids": [
+      "22802"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      },
+      {
+        "name": "Sunrise MMS",
+        "apn": "mms.sunrise.ch",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.sunrise.ch",
+        "mmsproxy": "212.35.34.75:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Swisscom",
+    "ids": [
+      "22801"
+    ],
+    "apns": [
+      {
+        "name": "Swisscom GPRS",
+        "apn": "gprs.swisscom.ch",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Swisscom CAA",
+        "apn": "corporate.swisscom.ch",
+        "type": [
+          "internet"
+        ],
+        "username": "testprofil",
+        "password": "temporary"
+      },
+      {
+        "name": "Swisscom MMS",
+        "apn": "event.swisscom.ch",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Swisscom MMS",
+        "apn": "event.swisscom.ch",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.natel.ch:8079",
+        "mmsproxy": "192.168.210.2:8080"
+      }
+    ]
+  },
+  {
+    "name": "M-Budget",
+    "ids": [
+      "22801"
+    ],
+    "apns": [
+      {
+        "name": "Migros Data",
+        "apn": "gprs.swisscom.ch",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "MTN",
+    "ids": [
+      "61205"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MTN MMS",
+        "apn": "fast-mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://192.168.97.1/mmsc",
+        "mmsproxy": "192.168.97.1:3130",
+        "username": "mms"
+      },
+      {
+        "name": "MTN-MMS",
+        "apn": "myMTN",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.mtn.co.za/mms/wapenc",
+        "mmsproxy": "196.11.240.241:8080",
+        "username": "mtnmms",
+        "password": "mtnmms"
+      }
+    ]
+  },
+  {
+    "name": "Claro Chile",
+    "ids": [
+      "73003"
+    ],
+    "apns": [
+      {
+        "name": "Internet Movil",
+        "apn": "bam.clarochile.cl",
+        "type": [
+          "internet"
+        ],
+        "username": "clarochile",
+        "password": "clarochile"
+      },
+      {
+        "name": "Internet Movil",
+        "apn": "bap.clarochile.cl",
+        "type": [
+          "internet"
+        ],
+        "username": "clarochile",
+        "password": "clarochile"
+      }
+    ]
+  },
+  {
+    "name": "Entel PCS",
+    "ids": [
+      "73001"
+    ],
+    "apns": [
+      {
+        "name": "Banda Ancha Movil",
+        "apn": "imovil.entelpcs.cl",
+        "type": [
+          "internet"
+        ],
+        "username": "entelpcs",
+        "password": "entelpcs"
+      },
+      {
+        "name": "Internet Movil",
+        "apn": "bam.entelpcs.cl",
+        "type": [
+          "internet"
+        ],
+        "username": "entelpcs",
+        "password": "entelpcs"
+      }
+    ]
+  },
+  {
+    "name": "Movistar",
+    "ids": [
+      "73002"
+    ],
+    "apns": [
+      {
+        "name": "Banda Ancha Movil",
+        "apn": "web.tmovil.cl",
+        "type": [
+          "internet"
+        ],
+        "username": "web",
+        "password": "web"
+      },
+      {
+        "name": "Internet Movil",
+        "apn": "wap.tmovil.cl",
+        "type": [
+          "internet"
+        ],
+        "username": "wap",
+        "password": "wap"
+      }
+    ]
+  },
+  {
+    "name": "GTD Movil",
+    "ids": [
+      "73007"
+    ],
+    "apns": [
+      {
+        "name": "Internet Movil",
+        "apn": "web.gtdmovil.cl",
+        "type": [
+          "internet"
+        ],
+        "username": "webgtd",
+        "password": "webgtd"
+      }
+    ]
+  },
+  {
+    "name": "Virgin Mobile",
+    "ids": [
+      "73007"
+    ],
+    "apns": [
+      {
+        "name": "Internet Movil",
+        "apn": "imovil.virginmobile.cl",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "VTR Movil",
+    "ids": [
+      "73008"
+    ],
+    "apns": [
+      {
+        "name": "Internet Movil",
+        "apn": "movil.vtr.com",
+        "type": [
+          "internet"
+        ],
+        "username": "vtrmovil",
+        "password": "vtrmovil"
+      }
+    ]
+  },
+  {
+    "name": "Wom",
+    "ids": [
+      "73009"
+    ],
+    "apns": [
+      {
+        "name": "Internet Movil",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "62402"
+    ],
+    "apns": [
+      {
+        "apn": "orangecmgprs",
+        "type": [
+          "internet"
+        ],
+        "username": "orange",
+        "password": "orange"
+      }
+    ]
+  },
+  {
+    "name": "MTN",
+    "ids": [
+      "62401"
+    ],
+    "apns": [
+      {
+        "apn": "INTERNET",
+        "type": [
+          "internet"
+        ],
+        "username": "guest",
+        "password": "guest"
+      }
+    ]
+  },
+  {
+    "name": "China Mobile",
+    "ids": [
+      "46002"
+    ],
+    "apns": [
+      {
+        "name": "WAP",
+        "apn": "cmwap",
+        "type": [
+          "wap"
+        ],
+        "username": "guest",
+        "password": "guest"
+      },
+      {
+        "name": "Internet",
+        "apn": "cmnet",
+        "type": [
+          "internet"
+        ],
+        "username": "guest",
+        "password": "guest"
+      },
+      {
+        "name": "移动彩信",
+        "apn": "cmwap",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.monternet.com",
+        "mmsproxy": "10.0.0.172:80"
+      }
+    ]
+  },
+  {
+    "name": "China Unicom",
+    "ids": [
+      "46001"
+    ],
+    "apns": [
+      {
+        "apn": "3gnet",
+        "type": [
+          "internet"
+        ],
+        "username": "uninet"
+      },
+      {
+        "name": "联通彩信",
+        "apn": "3gwap",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.myuni.com.cn",
+        "mmsproxy": "10.0.0.172:80"
+      }
+    ]
+  },
+  {
+    "name": "China Telecom",
+    "ids": [
+      "46011"
+    ],
+    "apns": [
+      {
+        "name": "CTNET",
+        "apn": "ctnet",
+        "type": [
+          "internet"
+        ],
+        "username": "ctnet@mycdma.cn",
+        "password": "vnet.mobi"
+      },
+      {
+        "name": "CTLTE",
+        "apn": "ctlte",
+        "type": [
+          "internet"
+        ],
+        "username": "ctlte@mycdma.cn",
+        "password": "vnet.mobi"
+      },
+      {
+        "name": "电信彩信",
+        "apn": "ctwap",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.vnet.mobi",
+        "mmsproxy": "10.0.0.200:80",
+        "username": "ctwap@mycdma.cn",
+        "password": "vnet.mobi"
+      }
+    ]
+  },
+  {
+    "name": "IceCelular",
+    "ids": [
+      "71201",
+      "71202"
+    ],
+    "apns": [
+      {
+        "apn": "icecelular",
+        "type": [
+          "internet"
+        ],
+        "username": "guest",
+        "password": "guest"
+      }
+    ]
+  },
+  {
+    "name": "Kolbi",
+    "ids": [
+      "71203"
+    ],
+    "apns": [
+      {
+        "name": "Kolbi 3g",
+        "apn": "kolbi3g",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS CLARO CR",
+        "apn": "mms.ideasclaro",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.ideasclaro.com:8002",
+        "mmsproxy": "216.230.133.66:8080"
+      }
+    ]
+  },
+  {
+    "name": "Claro",
+    "ids": [
+      "732101"
+    ],
+    "apns": [
+      {
+        "apn": "internet.comcel.com.co",
+        "type": [
+          "internet"
+        ],
+        "username": "COMCELWEB",
+        "password": "COMCELWEB"
+      }
+    ]
+  },
+  {
+    "name": "Movistar",
+    "ids": [
+      "732102",
+      "732123"
+    ],
+    "apns": [
+      {
+        "apn": "internet.movistar.com.co",
+        "type": [
+          "internet"
+        ],
+        "username": "movistar",
+        "password": "movistar"
+      }
+    ]
+  },
+  {
+    "name": "Tigo",
+    "ids": [
+      "732103",
+      "732111"
+    ],
+    "apns": [
+      {
+        "apn": "web.colombiamovil.com.co",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Tigo MMS",
+        "apn": "mms.sentelgsm.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.tigo.sn",
+        "mmsproxy": "172.16.16.16:8080",
+        "username": "tigo",
+        "password": "tigo"
+      }
+    ]
+  },
+  {
+    "name": "UNE",
+    "ids": [
+      "732103",
+      "732111"
+    ],
+    "apns": [
+      {
+        "apn": "www.une.net.co",
+        "type": [
+          "internet"
+        ],
+        "username": "une",
+        "password": "une"
+      },
+      {
+        "name": "LTE (4G)",
+        "apn": "une4glte.net.co",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "TIGO multimedia",
+        "apn": "mms.colombiamovil.com.co",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.ola.com.co",
+        "mmsproxy": "190.102.206.48:8080",
+        "username": "mms-cm1900",
+        "password": "mms-cm1900"
+      }
+    ]
+  },
+  {
+    "name": "Virgin Mobile",
+    "ids": [
+      "732123"
+    ],
+    "apns": [
+      {
+        "apn": "web.vmc.net.co",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "movistar MMS",
+        "apn": "mms.movistar.com.co",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.movistar.com.co",
+        "mmsproxy": "192.168.222.7:9001",
+        "username": "movistar",
+        "password": "movistar"
+      }
+    ]
+  },
+  {
+    "name": "Cytamobile-Vodafone",
+    "ids": [
+      "28001"
+    ],
+    "apns": [
+      {
+        "name": "Contract",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Prepaid",
+        "apn": "pp.internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "CytaMMS",
+        "apn": "cytamobile",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.cyta.com.cy",
+        "mmsproxy": "212.31.96.161:8080"
+      }
+    ]
+  },
+  {
+    "name": "MTN",
+    "ids": [
+      "28010"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "wap",
+        "password": "wap"
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "23003"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "O2",
+    "ids": [
+      "23002"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "apn": "internet.open",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Prepaid",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "02 MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.o2active.cz:8002",
+        "mmsproxy": "160.218.160.218:8080"
+      }
+    ]
+  },
+  {
+    "name": "T-Mobile",
+    "ids": [
+      "23001"
+    ],
+    "apns": [
+      {
+        "apn": "internet.t-mobile.cz",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "MOBIL.CZ",
+    "ids": [
+      "23001"
+    ],
+    "apns": [
+      {
+        "apn": "internet.t-mobile.cz",
+        "type": [
+          "internet"
+        ],
+        "username": "gprs",
+        "password": "gprs"
+      }
+    ]
+  },
+  {
+    "name": "AldiTalk/MedionMobile",
+    "ids": [
+      "26203",
+      "26205",
+      "26277"
+    ],
+    "apns": [
+      {
+        "name": "Volume rate/30 Day Flatrate",
+        "apn": "internet.eplus.de",
+        "type": [
+          "internet"
+        ],
+        "username": "eplus",
+        "password": "gprs"
+      },
+      {
+        "name": "E-plus MMS",
+        "apn": "mms.eplus.de",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms/eplus/",
+        "mmsproxy": "212.23.97.153:5080",
+        "username": "mms",
+        "password": "eplus"
+      }
+    ]
+  },
+  {
+    "name": "blau.de",
+    "ids": [
+      "26203",
+      "26205",
+      "26277"
+    ],
+    "apns": [
+      {
+        "apn": "internet.eplus.de",
+        "type": [
+          "internet"
+        ],
+        "username": "blau",
+        "password": "blau"
+      },
+      {
+        "name": "24 Hour Flatrate",
+        "apn": "tagesflat.eplus.de",
+        "type": [
+          "internet"
+        ],
+        "username": "blau",
+        "password": "blau"
+      }
+    ]
+  },
+  {
+    "name": "Bild Mobil",
+    "ids": [
+      "26202"
+    ],
+    "apns": [
+      {
+        "name": "BILD Mobilportal",
+        "apn": "access.vodafone.de",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Contract",
+        "apn": "web.vodafone.de",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "BILDmobil Speedstick (Surfpakete)",
+        "apn": "event.vodafone.de",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "VF DE MMS",
+        "apn": "event.vodafone.de",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://139.7.24.1/servlets/mms",
+        "mmsproxy": "139.7.29.17:80"
+      }
+    ]
+  },
+  {
+    "name": "E-Plus",
+    "ids": [
+      "26203",
+      "26205",
+      "26277"
+    ],
+    "apns": [
+      {
+        "apn": "internet.eplus.de",
+        "type": [
+          "internet"
+        ],
+        "username": "eplus",
+        "password": "gprs"
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "26243"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.de",
+        "type": [
+          "internet"
+        ],
+        "username": "lmde",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "O2",
+    "ids": [
+      "26207",
+      "26208",
+      "26211"
+    ],
+    "apns": [
+      {
+        "name": "LOOP",
+        "apn": "pinternet.interkom.de",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Pay-by-MB",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Pay-by-time",
+        "apn": "surfo2",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "o2 MMS",
+        "apn": "internet",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.81.0.7:8002",
+        "mmsproxy": "195.182.114.52:8080"
+      }
+    ]
+  },
+  {
+    "name": "Tchibo-Mobil",
+    "ids": [
+      "26207",
+      "26208",
+      "26211"
+    ],
+    "apns": [
+      {
+        "name": "Tagesflat / Monats-Flatrate L / Monats-Flatrate XL",
+        "apn": "webmobil1",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "T-Mobile(Telekom)",
+    "ids": [
+      "26201",
+      "26206"
+    ],
+    "apns": [
+      {
+        "name": "IPv4-only without NAT",
+        "apn": "internet.t-d1.de",
+        "type": [
+          "internet"
+        ],
+        "password": "t-d1"
+      },
+      {
+        "name": "Dualstack with MMS and fixed DNSv4",
+        "apn": "internet.t-mobile",
+        "type": [
+          "internet"
+        ],
+        "username": "t-mobile",
+        "password": "tm"
+      },
+      {
+        "name": "IPv6-only",
+        "apn": "internet.v6.telekom",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Default dualstack",
+        "apn": "internet.telekom",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Business Smart Connect",
+        "apn": "iot.telekom.net",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "T-Mobile MMS",
+        "apn": "internet.t-mobile",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.t-mobile.de/servlets/mms",
+        "mmsproxy": "172.28.23.131:8008",
+        "username": "t-mobile",
+        "password": "tm"
+      }
+    ]
+  },
+  {
+    "name": "Congstar",
+    "ids": [
+      "26201"
+    ],
+    "apns": [
+      {
+        "name": "Prepaid Contracts",
+        "apn": "internet.t-mobile",
+        "type": [
+          "internet"
+        ],
+        "username": "t-mobile",
+        "password": "tm"
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "26202",
+      "26204",
+      "26209"
+    ],
+    "apns": [
+      {
+        "apn": "web.vodafone.de",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "WebSessions",
+        "apn": "event.vodafone.de",
+        "type": [
+          "internet"
+        ],
+        "username": "vodafone",
+        "password": "vodafone"
+      }
+    ]
+  },
+  {
+    "name": "FONIC",
+    "ids": [
+      "26207",
+      "26208",
+      "26211"
+    ],
+    "apns": [
+      {
+        "apn": "pinternet.interkom.de",
+        "type": [
+          "internet"
+        ],
+        "username": "fonic",
+        "password": "fonic"
+      }
+    ]
+  },
+  {
+    "name": "simyo Internet",
+    "ids": [
+      "26203",
+      "26205",
+      "26277"
+    ],
+    "apns": [
+      {
+        "apn": "internet.eplus.de",
+        "type": [
+          "internet"
+        ],
+        "username": "simyo",
+        "password": "simyo"
+      }
+    ]
+  },
+  {
+    "name": "Alice",
+    "ids": [
+      "26207"
+    ],
+    "apns": [
+      {
+        "name": "Option Mobile",
+        "apn": "internet.partner1",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "1&1",
+    "ids": [
+      "26202",
+      "26204",
+      "26209"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Broadband",
+        "apn": "web.vodafone.de",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Mobile Web",
+        "apn": "mail.partner.de",
+        "type": [
+          "internet"
+        ],
+        "username": "D2",
+        "password": "Web"
+      }
+    ]
+  },
+  {
+    "name": "Netzclub",
+    "ids": [
+      "26207",
+      "26208",
+      "26211"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "pinternet.interkom.de",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "3",
+    "ids": [
+      "23806"
+    ],
+    "apns": [
+      {
+        "name": "Bredbånd (standard)",
+        "apn": "bredband.tre.dk",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Bredbånd Premium Kontant",
+        "apn": "net.tre.dk",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "3 (standard for mobilkunder; spærret for indgående trafik)",
+        "apn": "data.tre.dk",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "3 (statisk IP)",
+        "apn": "static.tre.dk",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "OiSTER",
+    "ids": [
+      "23806"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Broadband",
+        "apn": "bredband.oister.dk",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Mobile Internet",
+        "apn": "data.dk",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "3mms",
+        "apn": "data.tre.dk",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.3.dk",
+        "mmsproxy": "mmsproxy.3.dk:8799"
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "23812"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.dk",
+        "type": [
+          "internet"
+        ],
+        "username": "lmdk",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "Telenor",
+    "ids": [
+      "23802",
+      "23877"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Telenor MMS",
+        "apn": "telenor",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.telenor.dk",
+        "mmsproxy": "212.88.64.8:8080"
+      }
+    ]
+  },
+  {
+    "name": "CBB Mobil",
+    "ids": [
+      "23802",
+      "23877"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "TDC",
+    "ids": [
+      "23801"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "apn": "internet.no",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "apn": "internet.se",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "TDC MMS",
+        "apn": "mms.tdc.fi",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.tdc.fi",
+        "mmsproxy": "10.1.12.2:8080"
+      }
+    ]
+  },
+  {
+    "name": "Telia",
+    "ids": [
+      "23830"
+    ],
+    "apns": [
+      {
+        "apn": "www.internet.mtelia.dk",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Telia MMS",
+        "apn": "www.mms.mtelia.dk",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.telia.dk",
+        "mmsproxy": "193.209.134.131:8080"
+      }
+    ]
+  },
+  {
+    "name": "BiBoB",
+    "ids": [
+      "23802"
+    ],
+    "apns": [
+      {
+        "apn": "internet.bibob.dk",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Telmore",
+    "ids": [
+      "23801"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Telmore MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://192.168.241.114:8002",
+        "mmsproxy": "194.182.251.15:8080"
+      }
+    ]
+  },
+  {
+    "name": "Unotel",
+    "ids": [
+      "23801"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "happiimobil",
+    "ids": [
+      "23801"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Onfone Internet DK",
+    "ids": [
+      "23801"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "37001"
+    ],
+    "apns": [
+      {
+        "apn": "orangenet.com.do",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Claro",
+    "ids": [
+      "37002"
+    ],
+    "apns": [
+      {
+        "apn": "internet.ideasclaro.com.do",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Viva",
+    "ids": [
+      "37004"
+    ],
+    "apns": [
+      {
+        "apn": "edge.viva.net.do",
+        "type": [
+          "internet"
+        ],
+        "username": "viva",
+        "password": "viva"
+      }
+    ]
+  },
+  {
+    "name": "Djezzy",
+    "ids": [
+      "60302"
+    ],
+    "apns": [
+      {
+        "apn": "djezzy.internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Mobilis",
+    "ids": [
+      "60301"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      },
+      {
+        "name": "Mobilis MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://172.25.49.9/servlets/mms",
+        "mmsproxy": "172.25.49.2:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Nedjma",
+    "ids": [
+      "60303"
+    ],
+    "apns": [
+      {
+        "name": "WEB",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "nedjma",
+        "password": "nedjma"
+      },
+      {
+        "name": "Nedjma MMS",
+        "apn": "nedjmaMMS",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.10.111.1",
+        "mmsproxy": "192.168.52.3:3128",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Porta 3G",
+    "ids": [
+      "74001"
+    ],
+    "apns": [
+      {
+        "apn": "internet.porta.com.ec",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS Porta",
+        "apn": "mms.porta.com.ec",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://iesmms.porta.com.ec",
+        "mmsproxy": "216.250.208.94:8799",
+        "username": "portamms",
+        "password": "portamms2003"
+      }
+    ]
+  },
+  {
+    "name": "EMT",
+    "ids": [
+      "24801"
+    ],
+    "apns": [
+      {
+        "apn": "internet.emt.ee",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "EMT MMS",
+        "apn": "mms.emt.ee",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.emt.ee/servlets/mms",
+        "mmsproxy": "217.71.32.82:8080"
+      }
+    ]
+  },
+  {
+    "name": "Nordea",
+    "ids": [
+      "24801"
+    ],
+    "apns": [
+      {
+        "apn": "internet.emt.ee",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Elisa",
+    "ids": [
+      "24802"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Elisa MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.elisa.fi",
+        "mmsproxy": "213.161.41.57:80"
+      },
+      {
+        "name": "Elisa MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://194.204.2.10",
+        "mmsproxy": "194.204.2.6:8000"
+      }
+    ]
+  },
+  {
+    "name": "Tele2",
+    "ids": [
+      "24803"
+    ],
+    "apns": [
+      {
+        "apn": "internet.tele2.ee",
+        "type": [
+          "internet"
+        ],
+        "username": "wap",
+        "password": "wap"
+      },
+      {
+        "name": "Tele2 MMS",
+        "apn": "internet.tele2.fi",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.tele2.fi",
+        "mmsproxy": "193.12.40.19:80",
+        "username": "wap",
+        "password": "wap"
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "60202"
+    ],
+    "apns": [
+      {
+        "apn": "internet.vodafone.net",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      },
+      {
+        "name": "MMS Vodafone.eg",
+        "apn": "mms.vodafone.eg",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.vodafone.com.eg/servlets/mms",
+        "mmsproxy": "163.121.178.2:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Etisalat",
+    "ids": [
+      "60203"
+    ],
+    "apns": [
+      {
+        "apn": "etisalat",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Etisalat MMS",
+        "apn": "Etisalat",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.71.131.7:38090/",
+        "mmsproxy": "10.71.130.29:8080"
+      }
+    ]
+  },
+  {
+    "name": "MobiNil",
+    "ids": [
+      "60201"
+    ],
+    "apns": [
+      {
+        "apn": "mobinilweb",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MobiNil MMS",
+        "apn": "mobinilmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.7.13.24:8002/",
+        "mmsproxy": "62.241.155.45:8080"
+      }
+    ]
+  },
+  {
+    "name": "Euskaltel",
+    "ids": [
+      "21408"
+    ],
+    "apns": [
+      {
+        "apn": "internet.euskaltel.mobi",
+        "type": [
+          "internet"
+        ],
+        "username": "CLIENTE",
+        "password": "EUSKALTEL"
+      },
+      {
+        "name": "Euskaltel MMS",
+        "apn": "euskaltelmms.euskaltel.mobi",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.euskaltel.mobi/",
+        "mmsproxy": "172.16.18.74"
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "21425"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.es",
+        "type": [
+          "internet"
+        ],
+        "username": "lmes",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "Másmovil",
+    "ids": [
+      "21403"
+    ],
+    "apns": [
+      {
+        "apn": "internetmas",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "móbil R (Mundo-R)",
+    "ids": [
+      "21417"
+    ],
+    "apns": [
+      {
+        "apn": "internet.mundo-r.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Happy Móvil/moviData",
+    "ids": [
+      "21403"
+    ],
+    "apns": [
+      {
+        "apn": "INTERNETTPH",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "ONO",
+    "ids": [
+      "21418"
+    ],
+    "apns": [
+      {
+        "apn": "internet.ono.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Pepephone",
+    "ids": [
+      "21406"
+    ],
+    "apns": [
+      {
+        "name": "Pepephone",
+        "apn": "gprs.pepephone.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Pepephone (Mobile)",
+        "apn": "gprsmov.pepephone.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "21403",
+      "21409"
+    ],
+    "apns": [
+      {
+        "name": "Orange",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "ORANGE",
+        "password": "ORANGE"
+      }
+    ]
+  },
+  {
+    "name": "Simyo",
+    "ids": [
+      "21419"
+    ],
+    "apns": [
+      {
+        "apn": "gprs-service.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Telecable",
+    "ids": [
+      "21416"
+    ],
+    "apns": [
+      {
+        "apn": "internet.telecable.es",
+        "type": [
+          "internet"
+        ],
+        "username": "telecable",
+        "password": "telecable"
+      }
+    ]
+  },
+  {
+    "name": "Movistar (Telefónica)",
+    "ids": [
+      "21405",
+      "21407"
+    ],
+    "apns": [
+      {
+        "name": "Telefónica",
+        "apn": "telefonica.es",
+        "type": [
+          "internet"
+        ],
+        "username": "telefonica",
+        "password": "telefonica"
+      },
+      {
+        "name": "Movistar (USB modems)",
+        "apn": "movistar.es",
+        "type": [
+          "internet"
+        ],
+        "username": "movistar",
+        "password": "movistar"
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "21401",
+      "21406"
+    ],
+    "apns": [
+      {
+        "name": "Vodafone",
+        "apn": "ac.vodafone.es",
+        "type": [
+          "internet"
+        ],
+        "username": "vodafone",
+        "password": "vodafone"
+      },
+      {
+        "name": "Airtel (old)",
+        "apn": "airtelnet.es",
+        "type": [
+          "internet"
+        ],
+        "username": "vodafone",
+        "password": "vodafone"
+      },
+      {
+        "name": "MMS VODAFONE",
+        "apn": "mms.vodafone.net",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.vodafone.es/servlets/mms",
+        "mmsproxy": "212.73.32.10:80",
+        "username": "wap@wap",
+        "password": "wap125"
+      }
+    ]
+  },
+  {
+    "name": "Yoigo",
+    "ids": [
+      "21404"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Yoigo MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmss/",
+        "mmsproxy": "193.209.134.141:80"
+      }
+    ]
+  },
+  {
+    "name": "Jazztel",
+    "ids": [
+      "21421"
+    ],
+    "apns": [
+      {
+        "apn": "jazzinternet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Tuenti Móvil",
+    "ids": [
+      "21405"
+    ],
+    "apns": [
+      {
+        "apn": "tuenti.com",
+        "type": [
+          "internet"
+        ],
+        "username": "tuenti",
+        "password": "tuenti"
+      }
+    ]
+  },
+  {
+    "name": "LlamaYa móvil",
+    "ids": [
+      "21403"
+    ],
+    "apns": [
+      {
+        "apn": "moreinternet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Amena",
+    "ids": [
+      "21403"
+    ],
+    "apns": [
+      {
+        "apn": "orangeworld",
+        "type": [
+          "internet"
+        ],
+        "username": "orange",
+        "password": "orange"
+      }
+    ]
+  },
+  {
+    "name": "Ethio Telecom",
+    "ids": [
+      "63601"
+    ],
+    "apns": [
+      {
+        "apn": "etc.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Vodafone FO",
+    "ids": [
+      "28802"
+    ],
+    "apns": [
+      {
+        "apn": "vmc.vodafone.fo",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Kuiri",
+    "ids": [
+      "24431"
+    ],
+    "apns": [
+      {
+        "name": "Kuiri Internet",
+        "apn": "kuirinet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "DNA",
+    "ids": [
+      "24412"
+    ],
+    "apns": [
+      {
+        "name": "Postpaid (contract) NAT (available for all subscribers)",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Postpaid (contract) public IP address (Dec 2016 and later individual subscriptions)",
+        "apn": "julkinen.dna.fi",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Postpaid (contract) public IP address (Nov 2016 and earlier individual, and all company subscriptions)",
+        "apn": "data.dna.fi",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Moi Mobiili",
+        "apn": "data.moimobile.fi",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.dnafinland.fi",
+        "mmsproxy": "10.1.1.2:8080",
+        "username": "dna",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Elisa",
+    "ids": [
+      "24405"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Saunalahti",
+    "ids": [
+      "24421"
+    ],
+    "apns": [
+      {
+        "name": "Postpaid (contract) NAT (available for all subscribers)",
+        "apn": "internet.saunalahti",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Postpaid (contract) public IP address (needs to be ordered)",
+        "apn": "internet4",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Prepaid (no contract)",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Saunalahti MMS",
+        "apn": "mms.saunalahti.fi",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.saunalahti.fi:8002/",
+        "mmsproxy": "62.142.4.197:8080"
+      }
+    ]
+  },
+  {
+    "name": "Telia",
+    "ids": [
+      "24491"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Open Gate (public IP, open ports; needs to be ordered)",
+        "apn": "opengate",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Prointernet (public IP)",
+        "apn": "prointernet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "TeleFinland MMS",
+        "apn": "telefinland",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.sonera.net:8002",
+        "mmsproxy": "195.156.25.33:8080"
+      }
+    ]
+  },
+  {
+    "name": "Vodafone / Kidanet",
+    "ids": [
+      "54201"
+    ],
+    "apns": [
+      {
+        "apn": "vfinternet.fj",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "apn": "kidanet.fj",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "apn": "prepay.vfinternet.fj",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Bouygues Telecom",
+    "ids": [
+      "20820",
+      "20821"
+    ],
+    "apns": [
+      {
+        "name": "Contrat Pro Data Illimité",
+        "apn": "a2bouygtel.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "B2Bouygtel",
+        "apn": "b2bouygtel.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Forfait Data",
+        "apn": "ebouygtel.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Forfait Data",
+        "apn": "mmsbouygtel.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Contrat Pro Data",
+        "apn": "pcebouygtel.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Bouygues MMS",
+        "apn": "mmsbouygtel.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.bouyguestelecom.fr/mms/wapenc",
+        "mmsproxy": "62.201.129.226:8080"
+      }
+    ]
+  },
+  {
+    "name": "Free Mobile",
+    "ids": [
+      "20815"
+    ],
+    "apns": [
+      {
+        "name": "Free-Mobile",
+        "apn": "free",
+        "type": [
+          "internet"
+        ],
+        "username": "free",
+        "password": "free"
+      },
+      {
+        "name": "MMS Free",
+        "apn": "mmsfree",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.free.fr",
+        "mmsproxy": "10.0.0.10:8080"
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "20825"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.fr",
+        "type": [
+          "internet"
+        ],
+        "username": "lmfr",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "20801"
+    ],
+    "apns": [
+      {
+        "name": "Orange Internet",
+        "apn": "orange.fr",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Business Contract",
+        "apn": "internet-entreprise",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "No Contract / Mobicarte",
+        "apn": "orange",
+        "type": [
+          "internet"
+        ],
+        "username": "orange",
+        "password": "orange"
+      },
+      {
+        "name": "Orange Entreprises",
+        "apn": "orange-mib",
+        "type": [
+          "internet"
+        ],
+        "username": "mportail",
+        "password": "mib"
+      },
+      {
+        "name": "Orange MMS",
+        "apn": "orange-acte",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.orange.fr",
+        "mmsproxy": "192.168.10.200:8080",
+        "username": "orange",
+        "password": "orange"
+      },
+      {
+        "name": "Internet Everywhere 3G",
+        "apn": "orange.ie",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Prixtel",
+    "ids": [
+      "20801",
+      "20810"
+    ],
+    "apns": [
+      {
+        "name": "via Orange",
+        "apn": "Orange",
+        "type": [
+          "internet"
+        ],
+        "username": "orange",
+        "password": "orange"
+      },
+      {
+        "name": "via Orange",
+        "apn": "orange.acte",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.orange.fr",
+        "mmsproxy": "192.168.10.200:8080",
+        "username": "orange",
+        "password": "orange"
+      },
+      {
+        "name": "via SFR",
+        "apn": "sl2sfr",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "via SFR",
+        "apn": "sl2sfr",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms1",
+        "mmsproxy": "10.151.0.1:8080"
+      }
+    ]
+  },
+  {
+    "name": "SFR",
+    "ids": [
+      "20810",
+      "20811"
+    ],
+    "apns": [
+      {
+        "name": "Web / Prepaid",
+        "apn": "websfr",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "WAP",
+        "apn": "wapsfr",
+        "type": [
+          "wap"
+        ]
+      },
+      {
+        "name": "SFR internetpro",
+        "apn": "internetpro",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "SFR ipnet",
+        "apn": "ipnet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Mobile Broadband",
+        "apn": "slsfr",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Full Internet (Webphone)",
+        "apn": "sl2sfr",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Internet (Neuf Telecom)",
+        "apn": "internetneuf",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "mms65",
+        "apn": "mms65",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms65",
+        "mmsproxy": "10.143.156.8"
+      }
+    ]
+  },
+  {
+    "name": "Transatel Telecom",
+    "ids": [
+      "20822"
+    ],
+    "apns": [
+      {
+        "apn": "netgprs.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "TEN",
+    "ids": [
+      "20801"
+    ],
+    "apns": [
+      {
+        "apn": "ao.fr",
+        "type": [
+          "internet"
+        ],
+        "username": "orange",
+        "password": "orange"
+      },
+      {
+        "name": "Pay-by-MB",
+        "apn": "ofnew.fr",
+        "type": [
+          "internet"
+        ],
+        "username": "orange",
+        "password": "orange"
+      },
+      {
+        "name": "Orange acte",
+        "apn": "orange.acte",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.orange.fr",
+        "mmsproxy": "192.168.10.200:8080",
+        "username": "orange",
+        "password": "orange"
+      }
+    ]
+  },
+  {
+    "name": "TeleCoop",
+    "ids": [
+      "20801"
+    ],
+    "apns": [
+      {
+        "name": "Orange Internet",
+        "apn": "orange",
+        "type": [
+          "internet"
+        ],
+        "username": "orange",
+        "password": "orange"
+      },
+      {
+        "name": "Orange MMS",
+        "apn": "orange.acte",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.orange.fr",
+        "mmsproxy": "192.168.10.200:8080",
+        "username": "orange",
+        "password": "orange"
+      }
+    ]
+  },
+  {
+    "name": "AIF",
+    "ids": [
+      "20801",
+      "20828"
+    ],
+    "apns": [
+      {
+        "name": "Datapro",
+        "apn": "DATAPRO",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Simplus",
+    "ids": [
+      "20826",
+      "208260"
+    ],
+    "apns": [
+      {
+        "name": "NRJWEB",
+        "apn": "fnetnrj",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "NRJMMS",
+        "apn": "mmsnrj",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsnrj",
+        "mmsproxy": "10.143.156.5:8080"
+      }
+    ]
+  },
+  {
+    "name": "EE",
+    "ids": [
+      "23430",
+      "23433",
+      "23434",
+      "23486"
+    ],
+    "apns": [
+      {
+        "name": "EE Internet",
+        "apn": "everywhere",
+        "type": [
+          "internet"
+        ],
+        "username": "eesecure",
+        "password": "secure"
+      },
+      {
+        "name": "EE MMS",
+        "apn": "eezone",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms/",
+        "mmsproxy": "149.254.201.135:8080",
+        "username": "eesecure",
+        "password": "secure"
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "23426"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.co.uk",
+        "type": [
+          "internet"
+        ],
+        "username": "lmuk",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "O2",
+    "ids": [
+      "23402",
+      "23410",
+      "23411"
+    ],
+    "apns": [
+      {
+        "name": "Contract",
+        "apn": "mobile.o2.co.uk",
+        "type": [
+          "internet"
+        ],
+        "username": "o2web",
+        "password": "password"
+      },
+      {
+        "name": "Contract (faster)",
+        "apn": "mobile.o2.co.uk",
+        "type": [
+          "internet"
+        ],
+        "username": "faster",
+        "password": "password"
+      },
+      {
+        "name": "Pay and Go (Prepaid)",
+        "apn": "payandgo.o2.co.uk",
+        "type": [
+          "internet"
+        ],
+        "username": "payandgo",
+        "password": "payandgo"
+      },
+      {
+        "name": "iPhone (Contract)",
+        "apn": "idata.o2.co.uk",
+        "type": [
+          "internet"
+        ],
+        "username": "vertigo",
+        "password": "password"
+      },
+      {
+        "name": "Mobile Broadband",
+        "apn": "m-bb.o2.co.uk",
+        "type": [
+          "internet"
+        ],
+        "username": "o2bb",
+        "password": "password"
+      },
+      {
+        "name": "WAP",
+        "apn": "wap.o2.co.uk",
+        "type": [
+          "wap"
+        ],
+        "username": "o2wap",
+        "password": "password"
+      }
+    ]
+  },
+  {
+    "name": "Superdrug",
+    "ids": [
+      "23420"
+    ],
+    "apns": [
+      {
+        "apn": "superdrug.net",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "apn": "superdrug.net",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.um.three.co.uk:10021/mmsc",
+        "mmsproxy": "217.171.129.2:8799"
+      }
+    ]
+  },
+  {
+    "name": "giffgaff",
+    "ids": [
+      "23402",
+      "23410",
+      "23411"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Broadband",
+        "apn": "giffgaff.com",
+        "type": [
+          "internet"
+        ],
+        "username": "giffgaff",
+        "password": "password"
+      },
+      {
+        "name": "O2 MMS",
+        "apn": "wap.o2.co.uk",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.mms.o2.co.uk:8002",
+        "mmsproxy": "193.113.200.195:8080",
+        "username": "o2wap",
+        "password": "password"
+      }
+    ]
+  },
+  {
+    "name": "Tesco Mobile",
+    "ids": [
+      "23402",
+      "23410",
+      "23411"
+    ],
+    "apns": [
+      {
+        "apn": "prepay.tesco-mobile.com",
+        "type": [
+          "internet"
+        ],
+        "username": "tescowap",
+        "password": "password"
+      }
+    ]
+  },
+  {
+    "name": "Virgin Mobile",
+    "ids": [
+      "23431",
+      "23432"
+    ],
+    "apns": [
+      {
+        "apn": "vdata",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "apn": "goto.virginmobile.uk",
+        "type": [
+          "internet"
+        ],
+        "username": "user"
+      },
+      {
+        "name": "VM acte GPRS",
+        "apn": "orange.acte",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.orange.fr",
+        "mmsproxy": "192.168.10.200:8080",
+        "username": "orange",
+        "password": "orange"
+      },
+      {
+        "name": "Virgin MMS",
+        "apn": "vmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.virginmobile.co.za",
+        "mmsproxy": "196.31.116.242:8080"
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "23415"
+    ],
+    "apns": [
+      {
+        "name": "Contract",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "web",
+        "password": "web"
+      },
+      {
+        "name": "Prepaid",
+        "apn": "pp.vodafone.co.uk",
+        "type": [
+          "internet"
+        ],
+        "username": "web",
+        "password": "web"
+      },
+      {
+        "name": "TopUp and Go",
+        "apn": "ppbundle.internet",
+        "type": [
+          "internet"
+        ],
+        "username": "web",
+        "password": "web"
+      },
+      {
+        "name": "TopUp and Go (older 1GB SIMs)",
+        "apn": "pp.internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Asda Mobile",
+    "ids": [
+      "23415"
+    ],
+    "apns": [
+      {
+        "apn": "asdamobiles.co.uk",
+        "type": [
+          "internet"
+        ],
+        "username": "web",
+        "password": "web"
+      },
+      {
+        "name": "ASDA MMS",
+        "apn": "asdamobiles.co.uk",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.asdamobiles.co.uk/servlets/mms",
+        "mmsproxy": "212.183.137.12:8799",
+        "username": "wap",
+        "password": "wap"
+      }
+    ]
+  },
+  {
+    "name": "3",
+    "ids": [
+      "23420"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "3internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Handsets",
+        "apn": "three.co.uk",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Geocell",
+    "ids": [
+      "28201"
+    ],
+    "apns": [
+      {
+        "apn": "Internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Geo MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.geocell.com.ge/cmmsc/post",
+        "mmsproxy": "10.11.240.7:8080"
+      }
+    ]
+  },
+  {
+    "name": "Airtel-Vodaphone",
+    "ids": [
+      "23403"
+    ],
+    "apns": [
+      {
+        "apn": "airtel-ci-gprs.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Sure (Cable & Wireless)",
+    "ids": [
+      "23455"
+    ],
+    "apns": [
+      {
+        "name": "WAP",
+        "apn": "wap",
+        "type": [
+          "wap"
+        ]
+      },
+      {
+        "name": "Internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Lifestyle MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.gprs.cw.com/",
+        "mmsproxy": "10.0.3.101:80"
+      }
+    ]
+  },
+  {
+    "name": "Wave Telecom",
+    "ids": [
+      "23450"
+    ],
+    "apns": [
+      {
+        "apn": "pepper",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "pepperMMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.surfmail.com/mmsc",
+        "mmsproxy": "212.9.19.199:3130",
+        "username": "mms"
+      }
+    ]
+  },
+  {
+    "name": "MTN",
+    "ids": [
+      "62001"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "62002"
+    ],
+    "apns": [
+      {
+        "apn": "browse",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Tigo",
+    "ids": [
+      "62003"
+    ],
+    "apns": [
+      {
+        "apn": "web.tigo.com.gh",
+        "type": [
+          "internet"
+        ],
+        "username": "web"
+      }
+    ]
+  },
+  {
+    "name": "Airtel",
+    "ids": [
+      "62006"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "GloGhana",
+    "ids": [
+      "62007"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Cosmote MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.cosmote.gr:8002",
+        "mmsproxy": "10.10.10.20:8080"
+      }
+    ]
+  },
+  {
+    "name": "Cosmote",
+    "ids": [
+      "20201"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "20205"
+    ],
+    "apns": [
+      {
+        "name": "Contract",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Mobile Broadband On Demand",
+        "apn": "web.session",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Wind",
+    "ids": [
+      "20209",
+      "20210"
+    ],
+    "apns": [
+      {
+        "apn": "gint.b-online.gr",
+        "type": [
+          "internet"
+        ],
+        "username": "web",
+        "password": "web"
+      },
+      {
+        "name": "Q-Telecom MMS",
+        "apn": "q-mms.myq.gr",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.myq.gr",
+        "mmsproxy": "192.168.80.134:8080"
+      }
+    ]
+  },
+  {
+    "name": "Claro",
+    "ids": [
+      "70401"
+    ],
+    "apns": [
+      {
+        "apn": "internet.ideasclaro",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Comcel / Tigo",
+    "ids": [
+      "70402"
+    ],
+    "apns": [
+      {
+        "apn": "Wap.tigo.gt",
+        "type": [
+          "internet"
+        ],
+        "username": "Wap",
+        "password": "Wap"
+      },
+      {
+        "name": "MMS TIGO",
+        "apn": "mms.tigo.gt",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms",
+        "mmsproxy": "10.16.17.12:8888"
+      }
+    ]
+  },
+  {
+    "name": "Movistar",
+    "ids": [
+      "70403"
+    ],
+    "apns": [
+      {
+        "apn": "internet.movistar.gt",
+        "type": [
+          "internet"
+        ],
+        "username": "movistargt",
+        "password": "movistargt"
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "61101"
+    ],
+    "apns": [
+      {
+        "apn": "internetogn",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Cellcom",
+    "ids": [
+      "61105"
+    ],
+    "apns": [
+      {
+        "apn": "internet.cellcom.com",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "cellcom"
+      }
+    ]
+  },
+  {
+    "name": "GT&T Cellink Plus",
+    "ids": [
+      "73802"
+    ],
+    "apns": [
+      {
+        "apn": "wap.cellinkgy.com",
+        "type": [
+          "internet"
+        ],
+        "username": "test",
+        "password": "test"
+      }
+    ]
+  },
+  {
+    "name": "DigiCel",
+    "ids": [
+      "73801"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "web",
+        "password": "web"
+      },
+      {
+        "name": "Digicel Guyana MMS",
+        "apn": "wap.digicelgy.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmc.digicelgy.com/servlets/mms",
+        "mmsproxy": "172.20.6.12:8080",
+        "username": "wap",
+        "password": "wap"
+      }
+    ]
+  },
+  {
+    "name": "CSL",
+    "ids": [
+      "45402"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "CSL MMS",
+        "apn": "hkcsl",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://192.168.58.171:8002",
+        "mmsproxy": "192.168.59.51:8080"
+      }
+    ]
+  },
+  {
+    "name": "New World",
+    "ids": [
+      "45410"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "CMHK MMS",
+        "apn": "peoples.mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.hk.chinamobile.com/mms",
+        "mmsproxy": "172.31.31.36:8080"
+      }
+    ]
+  },
+  {
+    "name": "China Mobile",
+    "ids": [
+      "45412"
+    ],
+    "apns": [
+      {
+        "apn": "peoples.net",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "picturemail",
+        "apn": "SmarTone-Vodafone",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.smartone-vodafone.com/server",
+        "mmsproxy": "10.9.9.9:8080"
+      }
+    ]
+  },
+  {
+    "name": "SmarTone",
+    "ids": [
+      "45406"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "PCCW (Sunday)",
+    "ids": [
+      "45416",
+      "45419"
+    ],
+    "apns": [
+      {
+        "name": "Sunday (Old)",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "PCCW 2G/GPRS",
+        "apn": "pccwdata",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "PCCW 3G",
+        "apn": "pccw",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "PCCW MMS",
+        "apn": "pccwmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.mms.pccwmobile.com:8002/",
+        "mmsproxy": "10.131.2.8:8080"
+      },
+      {
+        "name": "PCCW 3G MMS",
+        "apn": "pccw",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://3gmms.pccwmobile.com:8080/was",
+        "mmsproxy": "10.140.14.10:8080"
+      }
+    ]
+  },
+  {
+    "name": "Sunday",
+    "ids": [
+      "45416"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "45404"
+    ],
+    "apns": [
+      {
+        "apn": "web.orangehk.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "3",
+    "ids": [
+      "45403",
+      "45404"
+    ],
+    "apns": [
+      {
+        "name": "3G",
+        "apn": "mobile.three.com.hk",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "4G LTE",
+        "apn": "mobile.lte.three.com.hk",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "45423"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.hk",
+        "type": [
+          "internet"
+        ],
+        "username": "lmhk",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "Tigo",
+    "ids": [
+      "70802"
+    ],
+    "apns": [
+      {
+        "apn": "internet.tigo.hn",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "T-Mobile",
+    "ids": [
+      "21901"
+    ],
+    "apns": [
+      {
+        "apn": "web.htgprs",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "VIPNET",
+    "ids": [
+      "21910"
+    ],
+    "apns": [
+      {
+        "name": "Contract and Prepaid",
+        "apn": "data.vip.hr",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "GPRS 5",
+        "apn": "gprs5.vipnet.hr",
+        "type": [
+          "internet"
+        ],
+        "username": "38591",
+        "password": "38591"
+      },
+      {
+        "name": "GPRS 0",
+        "apn": "gprs0.vipnet.hr",
+        "type": [
+          "internet"
+        ],
+        "username": "38591",
+        "password": "38591"
+      },
+      {
+        "name": "3G",
+        "apn": "3g.vip.hr",
+        "type": [
+          "internet"
+        ],
+        "username": "38591",
+        "password": "38591"
+      },
+      {
+        "name": "MMS",
+        "apn": "mms.vipnet.hr",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.vipnet.hr/servlets/mms",
+        "mmsproxy": "212.91.99.91:8080"
+      }
+    ]
+  },
+  {
+    "name": "CARNet VIPNET",
+    "ids": [
+      "21910"
+    ],
+    "apns": [
+      {
+        "apn": "carnet.vip.hr",
+        "type": [
+          "internet"
+        ],
+        "username": "AAIEDU"
+      }
+    ]
+  },
+  {
+    "name": "CARNet Tele2",
+    "ids": [
+      "21902"
+    ],
+    "apns": [
+      {
+        "apn": "carnet.tele2.hr",
+        "type": [
+          "internet"
+        ],
+        "username": "AAIEDU"
+      },
+      {
+        "name": "Tele2 MMS",
+        "apn": "internet.tele2.hr",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.tele2.hr",
+        "mmsproxy": "193012040066:8080"
+      }
+    ]
+  },
+  {
+    "name": "Tele2",
+    "ids": [
+      "21902"
+    ],
+    "apns": [
+      {
+        "apn": "mobileinternet.tele2.hr",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Telenor",
+    "ids": [
+      "21601"
+    ],
+    "apns": [
+      {
+        "name": "mobilinternet",
+        "apn": "net",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Pannon MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.pgsm.hu/",
+        "mmsproxy": "84.225.255.1:8080"
+      }
+    ]
+  },
+  {
+    "name": "DIGI",
+    "ids": [
+      "21601"
+    ],
+    "apns": [
+      {
+        "name": "DIGI Move",
+        "apn": "digi",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "T-Mobile",
+    "ids": [
+      "21630"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "21670"
+    ],
+    "apns": [
+      {
+        "name": "Előf. Normál",
+        "apn": "standardnet.vodafone.net",
+        "type": [
+          "internet"
+        ],
+        "username": "vodawap",
+        "password": "vodawap"
+      },
+      {
+        "name": "Előf. töm.",
+        "apn": "internet.vodafone.net",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Felt. norm.",
+        "apn": "vitamax.snet.vodafone.net",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Vodafone (felt. töm.)",
+        "apn": "vitamax.internet.vodafone.net",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "3",
+    "ids": [
+      "51089"
+    ],
+    "apns": [
+      {
+        "name": "GPRS",
+        "apn": "3gprs",
+        "type": [
+          "internet"
+        ],
+        "username": "3gprs",
+        "password": "3gprs"
+      },
+      {
+        "name": "Monthly Internet Service",
+        "apn": "3data",
+        "type": [
+          "internet"
+        ],
+        "username": "3data",
+        "password": "3data"
+      }
+    ]
+  },
+  {
+    "name": "AXIS",
+    "ids": [
+      "51008"
+    ],
+    "apns": [
+      {
+        "apn": "AXIS",
+        "type": [
+          "internet"
+        ],
+        "username": "axis",
+        "password": "123456"
+      },
+      {
+        "name": "AXISmms",
+        "apn": "AXISmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.axis",
+        "mmsproxy": "10.8.3.8:8080",
+        "username": "AXIS",
+        "password": "123456"
+      }
+    ]
+  },
+  {
+    "name": "Indosat",
+    "ids": [
+      "51001",
+      "51021"
+    ],
+    "apns": [
+      {
+        "name": "IM3/Mentari Time-based",
+        "apn": "indosatgprs",
+        "type": [
+          "internet"
+        ],
+        "username": "indosat@durasi",
+        "password": "indosat@durasi"
+      },
+      {
+        "name": "IM3/Mentari Volume-based",
+        "apn": "indosatgprs",
+        "type": [
+          "internet"
+        ],
+        "username": "indosat",
+        "password": "indosat"
+      },
+      {
+        "name": "Matrix 3G/3.5G",
+        "apn": "indosatgprs",
+        "type": [
+          "internet"
+        ],
+        "username": "indosat",
+        "password": "indosat"
+      },
+      {
+        "name": "IndosatMMS",
+        "apn": "indosatmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.indosat.com",
+        "mmsproxy": "10.19.19.19:8080",
+        "username": "indosat",
+        "password": "indosat"
+      }
+    ]
+  },
+  {
+    "name": "Telkomsel",
+    "ids": [
+      "51010",
+      "51020"
+    ],
+    "apns": [
+      {
+        "apn": "telkomsel",
+        "type": [
+          "internet"
+        ],
+        "username": "wap",
+        "password": "wap123"
+      },
+      {
+        "name": "Flash Time-based",
+        "apn": "flash",
+        "type": [
+          "internet"
+        ],
+        "username": "foo",
+        "password": "bar"
+      },
+      {
+        "name": "Flash Volume-based",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "foo",
+        "password": "bar"
+      },
+      {
+        "name": "TSEL-MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.telkomsel.com",
+        "mmsproxy": "10.1.89.150:8000",
+        "username": "wap",
+        "password": "wap123"
+      }
+    ]
+  },
+  {
+    "name": "Excelcomindo (XL)",
+    "ids": [
+      "51011"
+    ],
+    "apns": [
+      {
+        "apn": "www.xlgprs.net",
+        "type": [
+          "internet"
+        ],
+        "username": "xlgprs",
+        "password": "proxl"
+      },
+      {
+        "name": "XL-MMS",
+        "apn": "www.xlmms.net",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmc.xl.net.id/servlets/mms",
+        "mmsproxy": "202.152.240.50:8080",
+        "username": "xlgprs",
+        "password": "proxl"
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "27213"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.ie",
+        "type": [
+          "internet"
+        ],
+        "username": "lmie",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "O2",
+    "ids": [
+      "27202"
+    ],
+    "apns": [
+      {
+        "name": "Contract",
+        "apn": "open.internet",
+        "type": [
+          "internet"
+        ],
+        "username": "gprs",
+        "password": "gprs"
+      },
+      {
+        "name": "Prepaid",
+        "apn": "pp.internet",
+        "type": [
+          "internet"
+        ],
+        "username": "faster",
+        "password": "web"
+      },
+      {
+        "name": "Old Config Internet and MMS",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "O2 MMS",
+        "apn": "internet",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.mms.o2.ie:8002",
+        "mmsproxy": "62.40.32.40:8080"
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "27201"
+    ],
+    "apns": [
+      {
+        "apn": "hs.vodafone.ie",
+        "type": [
+          "internet"
+        ],
+        "username": "vodafone",
+        "password": "vodafone"
+      },
+      {
+        "name": "Old",
+        "apn": "isp.vodafone.ie",
+        "type": [
+          "internet"
+        ],
+        "username": "vodafone",
+        "password": "vodafone"
+      },
+      {
+        "name": "Prepaid",
+        "apn": "live.vodafone.com",
+        "type": [
+          "internet"
+        ],
+        "username": "vodafone",
+        "password": "vodafone"
+      }
+    ]
+  },
+  {
+    "name": "E-Mobile",
+    "ids": [
+      "27203"
+    ],
+    "apns": [
+      {
+        "name": "Broadband To Go",
+        "apn": "broadband.eircommbb.ie",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS over GPRS",
+        "apn": "mms.mymeteor.ie",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.mymeteor.ie",
+        "mmsproxy": "10.85.85.85:8799",
+        "username": "my",
+        "password": "wap"
+      }
+    ]
+  },
+  {
+    "name": "Meteor",
+    "ids": [
+      "27203"
+    ],
+    "apns": [
+      {
+        "name": "Meteor Data",
+        "apn": "data.mymeteor.ie",
+        "type": [
+          "internet"
+        ],
+        "username": "my",
+        "password": "meteor"
+      },
+      {
+        "name": "Broadband To Go",
+        "apn": "broadband.mymeteor.ie",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "GPRS",
+        "apn": "isp.mymeteor.ie",
+        "type": [
+          "internet"
+        ],
+        "username": "my",
+        "password": "isp"
+      }
+    ]
+  },
+  {
+    "name": "Three Ireland",
+    "ids": [
+      "27205"
+    ],
+    "apns": [
+      {
+        "apn": "3ireland.ie",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "3MMS",
+        "apn": "3ireland.ie",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.um.3ireland.ie:10021/mmsc",
+        "mmsproxy": "mms.3ireland.ie:8799"
+      }
+    ]
+  },
+  {
+    "name": "CellCom",
+    "ids": [
+      "42502"
+    ],
+    "apns": [
+      {
+        "apn": "internetg",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Cellcom MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.cellcom.co.il",
+        "mmsproxy": "vwapm2.ain.co.il:8080"
+      }
+    ]
+  },
+  {
+    "name": "GolanTelecom",
+    "ids": [
+      "42508"
+    ],
+    "apns": [
+      {
+        "apn": "internet.golantelecom.net.il",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Golan Telecom MMS",
+        "apn": "mms.golantelecom.net.il",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.golantelecom.co.il",
+        "mmsproxy": "10.224.228.81:80"
+      }
+    ]
+  },
+  {
+    "name": "Home Cellular",
+    "ids": [
+      "42515"
+    ],
+    "apns": [
+      {
+        "apn": "hcminternet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Hot Mobile",
+    "ids": [
+      "42507"
+    ],
+    "apns": [
+      {
+        "apn": "net.hotm",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS HOT Mobile",
+        "apn": "mms.hotm",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.hotmobile.co.il",
+        "mmsproxy": "80.246.131.99"
+      }
+    ]
+  },
+  {
+    "name": "Partner",
+    "ids": [
+      "42501"
+    ],
+    "apns": [
+      {
+        "name": "3G Internet",
+        "apn": "uinternet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS Partner",
+        "apn": "wap.orange.co.il",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://192.168.220.15:8080/servlets/mms"
+      }
+    ]
+  },
+  {
+    "name": "Pelephone",
+    "ids": [
+      "42503"
+    ],
+    "apns": [
+      {
+        "name": "3G",
+        "apn": "internet.pelephone.net.il",
+        "type": [
+          "internet"
+        ],
+        "username": "pcl@3g",
+        "password": "pcl"
+      },
+      {
+        "name": "Multimedia Pelephone",
+        "apn": "mms.pelephone.net.il",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "mmsu.pelephone.net.il",
+        "mmsproxy": "10.170.9.54:9093",
+        "username": "pcl@3g",
+        "password": "pcl"
+      }
+    ]
+  },
+  {
+    "name": "Rami Levi",
+    "ids": [
+      "42516"
+    ],
+    "apns": [
+      {
+        "apn": "internet.rl",
+        "type": [
+          "internet"
+        ],
+        "username": "rl@3g",
+        "password": "rl"
+      },
+      {
+        "name": "Rami Levi MMS",
+        "apn": "mms.rl",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsu.pelephone.net.il",
+        "mmsproxy": "10.170.9.54:9093",
+        "username": "rl@3g",
+        "password": "rl"
+      }
+    ]
+  },
+  {
+    "name": "We4G",
+    "ids": [
+      "42509"
+    ],
+    "apns": [
+      {
+        "apn": "we",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "YouPhone 3G",
+    "ids": [
+      "42514"
+    ],
+    "apns": [
+      {
+        "apn": "data.youphone.co.il",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Multimedia Youphone",
+        "apn": "data.youphone.co.il",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://192.168.220.15/servlets/mms"
+      }
+    ]
+  },
+  {
+    "name": "Manx Telecom",
+    "ids": [
+      "23458"
+    ],
+    "apns": [
+      {
+        "apn": "3gpronto",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Pronto MMS",
+        "apn": "mms.manxpronto.net",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.manxpronto.net:8002",
+        "mmsproxy": "195.10.99.46:80",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Sure (Cable & Wireless)",
+    "ids": [
+      "23436",
+      "23455"
+    ],
+    "apns": [
+      {
+        "name": "WAP",
+        "apn": "wap",
+        "type": [
+          "wap"
+        ]
+      },
+      {
+        "name": "Internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "AIRCEL",
+    "ids": [
+      "40417",
+      "40428",
+      "40429",
+      "40437",
+      "40441",
+      "40442",
+      "40491",
+      "405800",
+      "405801",
+      "405802",
+      "405803",
+      "405804",
+      "405805",
+      "405806",
+      "405807",
+      "405808",
+      "405809",
+      "405810",
+      "405811",
+      "405812"
+    ],
+    "apns": [
+      {
+        "name": "Web",
+        "apn": "aircelweb",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "GPRS",
+        "apn": "aircelgprs",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "GPRS (Postpaid)",
+        "apn": "aircelgprs.po",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "GPRS (Prepaid)",
+        "apn": "aircelgprs.pr",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Aircel MMS",
+        "apn": "aircelmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://172.17.83.67/servlets/mms",
+        "mmsproxy": "172.17.83.69:8080"
+      },
+      {
+        "name": "Aircel MMS",
+        "apn": "aircelmms.po",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc/mmrelay.app",
+        "mmsproxy": "192.168.35.196:8081"
+      },
+      {
+        "name": "Aircel MMS",
+        "apn": "aircelmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc/mmrelay.app",
+        "mmsproxy": "192.168.35.196:8081"
+      }
+    ]
+  },
+  {
+    "name": "Airtel",
+    "ids": [
+      "40402",
+      "40403",
+      "40406",
+      "40410",
+      "40428",
+      "40431",
+      "40437",
+      "40440",
+      "40441",
+      "40442",
+      "40445",
+      "40449",
+      "40470",
+      "40490",
+      "40492",
+      "40493",
+      "40495",
+      "40496",
+      "40497",
+      "40498",
+      "40551",
+      "40552",
+      "40554",
+      "40556"
+    ],
+    "apns": [
+      {
+        "apn": "airtelgprs.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "40401",
+      "40405",
+      "40411",
+      "40413",
+      "40415",
+      "40420",
+      "40427",
+      "40430",
+      "40443",
+      "40446",
+      "40460",
+      "40484",
+      "40486",
+      "40488",
+      "40566",
+      "405750",
+      "405751",
+      "405752",
+      "405753",
+      "405754",
+      "405755",
+      "405756"
+    ],
+    "apns": [
+      {
+        "name": "Vodafone Connect",
+        "apn": "www",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "BSNL/CellOne",
+    "ids": [
+      "40434",
+      "40438",
+      "40451",
+      "40453",
+      "40454",
+      "40455",
+      "40457",
+      "40458",
+      "40459",
+      "40462",
+      "40464",
+      "40466",
+      "40471",
+      "40472",
+      "40473",
+      "40474",
+      "40475",
+      "40476",
+      "40477",
+      "40480",
+      "40481"
+    ],
+    "apns": [
+      {
+        "name": "New GPRS/3G",
+        "apn": "bsnlnet",
+        "type": [
+          "internet"
+        ],
+        "username": "MSISDN",
+        "password": "MSISDN"
+      },
+      {
+        "name": "New WAP",
+        "apn": "bsnlwap",
+        "type": [
+          "wap"
+        ]
+      },
+      {
+        "name": "Old South Zone A (Karnatka, Andhra Pradesh, Chennai, Tamil Nadu, Kerala)",
+        "apn": "bsnlsouth",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Old South Zone B (Karnatka, Andhra Pradesh, Chennai, Tamil Nadu, Kerala)",
+        "apn": "gprssouth.cellone.in",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Old North Zone (Haryana, Punjab, UP(East), UP(West), Himachal Pradesh, Rajasthan, Jammu & Kashmir)",
+        "apn": "gprsnorth.cellone.in",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Old West Zone (Maharashtra, Gujrat, Madhya Pradesh, Chattishgarh)",
+        "apn": "gprswest.cellone.in",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Old East Zone Prepaid (Jharkhand, Bihar, Kolkata, West Bengal, Orissa, Assam, North East, Adman Nicobar)",
+        "apn": "www.e.pr",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Old East Zone Postpaid (Jharkhand, Bihar, Kolkata, West Bengal, Orissa, Assam, North East, Adman Nicobar)",
+        "apn": "www.e.po",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "BSNL MMS",
+        "apn": "bsnlmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://bsnlmmsc.in:8514",
+        "mmsproxy": "10.210.10.11:8080"
+      }
+    ]
+  },
+  {
+    "name": "Idea Cellular",
+    "ids": [
+      "40404",
+      "40407",
+      "40412",
+      "40414",
+      "40419",
+      "40422",
+      "40424",
+      "40444",
+      "40456",
+      "40482",
+      "40570",
+      "405799",
+      "405845",
+      "405848",
+      "405850"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS Idea GPRS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.idea.pl",
+        "mmsproxy": "192.168.6.104:8080"
+      },
+      {
+        "name": "Idea MMS",
+        "apn": "mmsc",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.4.42.21:8002",
+        "mmsproxy": "10.4.42.15:8080"
+      }
+    ]
+  },
+  {
+    "name": "MTNL",
+    "ids": [
+      "40468",
+      "40469"
+    ],
+    "apns": [
+      {
+        "name": "Delhi (3G Prepaid / Postpaid)",
+        "apn": "mtnl.net",
+        "type": [
+          "internet"
+        ],
+        "username": "mtnl",
+        "password": "mtnl123"
+      },
+      {
+        "name": "Mumbai (3G Prepaid / Postpaid)",
+        "apn": "mtnl.net",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Delhi",
+        "apn": "gprsmtnldel",
+        "type": [
+          "internet"
+        ],
+        "username": "mtnl",
+        "password": "mtnl123"
+      },
+      {
+        "name": "Mumbai (Prepaid)",
+        "apn": "gprsppsmum",
+        "type": [
+          "internet"
+        ],
+        "username": "mtnl",
+        "password": "mtnl123"
+      },
+      {
+        "name": "Mumbai (Postpaid / Plan 2)",
+        "apn": "gprsmtnlmum",
+        "type": [
+          "internet"
+        ],
+        "username": "mtnl",
+        "password": "mtnl123"
+      },
+      {
+        "name": "MTNL MMS",
+        "apn": "mmsmtnldel",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://172.16.31.136/mms/",
+        "mmsproxy": "172.16.31.136:9401"
+      }
+    ]
+  },
+  {
+    "name": "Reliance",
+    "ids": [
+      "40409",
+      "40436",
+      "40452",
+      "40483",
+      "40485",
+      "40505",
+      "40510",
+      "40513"
+    ],
+    "apns": [
+      {
+        "name": "Smart Net",
+        "apn": "smartnet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Smart WAP",
+        "apn": "smartwap",
+        "type": [
+          "wap"
+        ]
+      },
+      {
+        "name": "Netconnect (RCOMNET)",
+        "apn": "rcomnet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "RMMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.239.221.47/mms/",
+        "mmsproxy": "10.239.221.7:8080"
+      },
+      {
+        "name": "Reliance MMS",
+        "apn": "rcommms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.rcom.co.in/mms/",
+        "mmsproxy": "10.239.221.5:8080"
+      }
+    ]
+  },
+  {
+    "name": "Spice telecom",
+    "ids": [
+      "40414",
+      "40444"
+    ],
+    "apns": [
+      {
+        "apn": "Simplyenjoy",
+        "type": [
+          "internet"
+        ],
+        "username": "spice",
+        "password": "spice"
+      },
+      {
+        "name": "kar",
+        "apn": "simplydownload",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Idea MMS",
+        "apn": "mmsc",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.4.42.21:8002/",
+        "mmsproxy": "10.4.42.15:8080"
+      }
+    ]
+  },
+  {
+    "name": "Tata Docomo",
+    "ids": [
+      "405025",
+      "405026",
+      "405027",
+      "405029",
+      "405030",
+      "405031",
+      "405032",
+      "405034",
+      "405035",
+      "405036",
+      "405037",
+      "405038",
+      "405039",
+      "405041",
+      "405042",
+      "405043",
+      "405044",
+      "405045",
+      "405046",
+      "405047"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "TATA.DOCOMO.INTERNET",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Internet",
+        "apn": "TATADOCOMO3G",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "TATA DOCOMO MMS",
+        "apn": "TATA.DOCOMO.MMS",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc/",
+        "mmsproxy": "10.124.26.94:8799"
+      }
+    ]
+  },
+  {
+    "name": "Korek",
+    "ids": [
+      "41840"
+    ],
+    "apns": [
+      {
+        "apn": "net.korek.com",
+        "type": [
+          "internet"
+        ],
+        "username": "korek",
+        "password": "korek"
+      }
+    ]
+  },
+  {
+    "name": "Asia Cell",
+    "ids": [
+      "41850"
+    ],
+    "apns": [
+      {
+        "apn": "net.asiacell.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Irancell-MMS",
+        "apn": "mtnirancell",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms:8002",
+        "mmsproxy": "10.131.26.138:9200"
+      }
+    ]
+  },
+  {
+    "name": "همراه اول",
+    "ids": [
+      "43211"
+    ],
+    "apns": [
+      {
+        "apn": "mcinet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "ایرانسل",
+    "ids": [
+      "43235"
+    ],
+    "apns": [
+      {
+        "apn": "mtnirancell",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "27402",
+      "27403"
+    ],
+    "apns": [
+      {
+        "apn": "vmc.gprs.is",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Nova",
+    "ids": [
+      "27411"
+    ],
+    "apns": [
+      {
+        "apn": "internet.nova.is",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Nova MMS",
+        "apn": "mms.nova.is",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.nova.is",
+        "mmsproxy": "10.10.2.60:8080"
+      }
+    ]
+  },
+  {
+    "name": "Síminn",
+    "ids": [
+      "27401"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Siminn MMS",
+        "apn": "mms.simi.is",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.simi.is/servlets/mms",
+        "mmsproxy": "213.167.138.200:9201"
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "22210"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Internet",
+        "apn": "mobile.vodafone.it",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Vodafone Internet Key",
+        "apn": "web.omnitel.it",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Internet Facile (old)",
+        "apn": "web.omnitel.it",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "TIM",
+    "ids": [
+      "22201"
+    ],
+    "apns": [
+      {
+        "name": "Maxxi Alice/Internet",
+        "apn": "ibox.tim.it",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "WAP",
+        "apn": "wap.tim.it",
+        "type": [
+          "wap"
+        ],
+        "username": "WAPTIM"
+      }
+    ]
+  },
+  {
+    "name": "Wind",
+    "ids": [
+      "22288"
+    ],
+    "apns": [
+      {
+        "name": "Non-business",
+        "apn": "internet.wind",
+        "type": [
+          "internet"
+        ],
+        "username": "Wind",
+        "password": "Wind"
+      },
+      {
+        "name": "Business",
+        "apn": "internet.wind.biz",
+        "type": [
+          "internet"
+        ],
+        "username": "Wind",
+        "password": "Wind"
+      },
+      {
+        "name": "WIND MMS",
+        "apn": "mms.wind",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.wind.it",
+        "mmsproxy": "212.245.244.100:8080"
+      }
+    ]
+  },
+  {
+    "name": "3",
+    "ids": [
+      "22299"
+    ],
+    "apns": [
+      {
+        "name": "Ricaricabile",
+        "apn": "tre.it",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Abbonamento",
+        "apn": "datacard.tre.it",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Fastweb",
+    "ids": [
+      "22299"
+    ],
+    "apns": [
+      {
+        "name": "Voce/dati",
+        "apn": "apn.fastweb.it",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Solo dati",
+        "apn": "datacard.fastweb.it",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "3 MMS",
+        "apn": "tre.it",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.216.59.240:10021/mmsc",
+        "mmsproxy": "wsb.treumts.it:8799"
+      }
+    ]
+  },
+  {
+    "name": "PosteMobile",
+    "ids": [
+      "22210"
+    ],
+    "apns": [
+      {
+        "apn": "internet.postemobile.it",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "PosteMobile MMS",
+        "apn": "mms.postemobile.it",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.postemobile.it/servlets/mms",
+        "mmsproxy": "10.128.224.10:80"
+      }
+    ]
+  },
+  {
+    "name": "CoopVoce",
+    "ids": [
+      "22201"
+    ],
+    "apns": [
+      {
+        "name": "Internet Mobile",
+        "apn": "web.coopvoce.it",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Rabona Mobile",
+    "ids": [
+      "22254"
+    ],
+    "apns": [
+      {
+        "name": "RABONA WEB",
+        "apn": "rabona.it",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Bip",
+    "ids": [
+      "22299"
+    ],
+    "apns": [
+      {
+        "name": "Megabip Internet",
+        "apn": "internet.vistream.it",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Nòverca",
+    "ids": [
+      "22207"
+    ],
+    "apns": [
+      {
+        "name": "Noverca WEB",
+        "apn": "web.noverca.it",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Noverca MMS",
+        "apn": "mms.noverca.it",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.noverca.it/",
+        "mmsproxy": "10.248.1.12:80"
+      },
+      {
+        "name": "Noverca WAP",
+        "apn": "wap.noverca.it",
+        "type": [
+          "wap"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Tiscali",
+    "ids": [
+      "22201"
+    ],
+    "apns": [
+      {
+        "name": "Tiscali Internet",
+        "apn": "tiscalimobileinternet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "22235"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.it",
+        "type": [
+          "internet"
+        ],
+        "username": "lmit",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "Iliad",
+    "ids": [
+      "22250"
+    ],
+    "apns": [
+      {
+        "name": "Iliad",
+        "apn": "iliad",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Iliad MMS",
+        "apn": "mms.iliad.it",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.iliad.it"
+      }
+    ]
+  },
+  {
+    "name": "Airtel-Vodaphone",
+    "ids": [
+      "23403"
+    ],
+    "apns": [
+      {
+        "apn": "airtel-ci-gprs.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Sure (Cable & Wireless)",
+    "ids": [
+      "23455"
+    ],
+    "apns": [
+      {
+        "name": "WAP",
+        "apn": "wap",
+        "type": [
+          "wap"
+        ]
+      },
+      {
+        "name": "Internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Jersey Telecom",
+    "ids": [
+      "23450"
+    ],
+    "apns": [
+      {
+        "apn": "pepper",
+        "type": [
+          "internet"
+        ],
+        "username": "abc",
+        "password": "abc"
+      }
+    ]
+  },
+  {
+    "name": "Cable & Wireless",
+    "ids": [
+      "338020"
+    ],
+    "apns": [
+      {
+        "apn": "wap",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Digicel",
+    "ids": [
+      "338050"
+    ],
+    "apns": [
+      {
+        "apn": "web.digiceljamaica.com",
+        "type": [
+          "internet"
+        ],
+        "username": "wapuser",
+        "password": "wap03jam"
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "41677"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Broadband",
+        "apn": "net.orange.jo",
+        "type": [
+          "internet"
+        ],
+        "username": "net",
+        "password": "net"
+      }
+    ]
+  },
+  {
+    "name": "Zain",
+    "ids": [
+      "41601"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Broadband",
+        "apn": "zain",
+        "type": [
+          "internet"
+        ],
+        "username": "Zain",
+        "password": "Zain"
+      },
+      {
+        "name": "Zain-MMS",
+        "apn": "Zain",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.122.200.12:8002",
+        "mmsproxy": "10.122.200.10:8080"
+      }
+    ]
+  },
+  {
+    "name": "Softbank Mobile",
+    "ids": [
+      "44004",
+      "44006",
+      "44020",
+      "44040",
+      "44041",
+      "44042",
+      "44043",
+      "44044",
+      "44045",
+      "44046",
+      "44047",
+      "44048",
+      "44090",
+      "44092",
+      "44093",
+      "44094",
+      "44095",
+      "44096",
+      "44097",
+      "44098"
+    ],
+    "apns": [
+      {
+        "apn": "softbank",
+        "type": [
+          "internet"
+        ],
+        "username": "ai@softbank",
+        "password": "softbank"
+      }
+    ]
+  },
+  {
+    "name": "b-mobile",
+    "ids": [
+      "44010"
+    ],
+    "apns": [
+      {
+        "name": "u300",
+        "apn": "dm.jplat.net",
+        "type": [
+          "internet"
+        ],
+        "username": "bmobile@u300",
+        "password": "bmobile"
+      },
+      {
+        "name": "Visitor SIM",
+        "apn": "bmobile.ne.jp",
+        "type": [
+          "internet"
+        ],
+        "username": "bmobile@4g",
+        "password": "bmobile"
+      }
+    ]
+  },
+  {
+    "name": "NTTdocomo",
+    "ids": [
+      "44001",
+      "44002",
+      "44003",
+      "44009",
+      "44010",
+      "44011",
+      "44012",
+      "44013",
+      "44014",
+      "44015",
+      "44016",
+      "44017",
+      "44018",
+      "44019",
+      "44021",
+      "44022",
+      "44023",
+      "44024",
+      "44025",
+      "44026",
+      "44027",
+      "44028",
+      "44029",
+      "44030",
+      "44031",
+      "44032",
+      "44033",
+      "44034",
+      "44035",
+      "44036",
+      "44037",
+      "44038",
+      "44039",
+      "44049",
+      "44058",
+      "44060",
+      "44061",
+      "44062",
+      "44063",
+      "44064",
+      "44065",
+      "44066",
+      "44067",
+      "44068",
+      "44069",
+      "44087",
+      "44099"
+    ],
+    "apns": [
+      {
+        "name": "mopera",
+        "apn": "mopera.ne.jp",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "mopera U",
+        "apn": "mopera.net",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "楽天モバイル",
+    "ids": [
+      "44011",
+      "44053"
+    ],
+    "apns": [
+      {
+        "name": "楽天 (rakuten.jp)",
+        "apn": "rakuten.jp",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "OCN",
+    "ids": [
+      "44010",
+      "44013"
+    ],
+    "apns": [
+      {
+        "name": "OCN モバイル ONE (3G)",
+        "apn": "3g-d-2.ocn.ne.jp",
+        "type": [
+          "internet"
+        ],
+        "authentication": "chap",
+        "username": "mobileid@ocn",
+        "password": "mobile"
+      },
+      {
+        "name": "OCN モバイル ONE",
+        "apn": "lte-d.ocn.ne.jp",
+        "type": [
+          "internet"
+        ],
+        "authentication": "chap",
+        "username": "mobileid@ocn",
+        "password": "mobile"
+      },
+      {
+        "name": "OCN モバイル ONE (新コース)",
+        "apn": "lte.ocn.ne.jp",
+        "type": [
+          "internet"
+        ],
+        "authentication": "chap",
+        "username": "mobileid@ocn",
+        "password": "mobile"
+      }
+    ]
+  },
+  {
+    "name": "Excite",
+    "ids": [
+      "44010",
+      "44051"
+    ],
+    "apns": [
+      {
+        "name": "エキサイトモバイル",
+        "apn": "vmobile.jp",
+        "type": [
+          "internet"
+        ],
+        "username": "bb@excite.co.jp",
+        "password": "excite"
+      }
+    ]
+  },
+  {
+    "name": "Mineo",
+    "ids": [
+      "44010"
+    ],
+    "apns": [
+      {
+        "name": "Mineo (Dプラン)",
+        "apn": "mineo-d.jp",
+        "type": [
+          "internet"
+        ],
+        "authentication": "chap",
+        "username": "mineo@k-opti.com",
+        "password": "mineo"
+      }
+    ]
+  },
+  {
+    "name": "Mineo",
+    "ids": [
+      "44051"
+    ],
+    "apns": [
+      {
+        "name": "Mineo (Aプラン)",
+        "apn": "mineo.jp",
+        "type": [
+          "internet"
+        ],
+        "authentication": "chap",
+        "username": "mineo@k-opti.com",
+        "password": "mineo"
+      }
+    ]
+  },
+  {
+    "name": "Mineo",
+    "ids": [
+      "44020"
+    ],
+    "apns": [
+      {
+        "name": "Mineo (Sプラン)",
+        "apn": "mineo-s.jp",
+        "type": [
+          "internet"
+        ],
+        "authentication": "chap",
+        "username": "mineo@k-opti.com",
+        "password": "mineo"
+      }
+    ]
+  },
+  {
+    "name": "Airtel",
+    "ids": [
+      "63903"
+    ],
+    "apns": [
+      {
+        "apn": "ke.celtel.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "YU mms",
+        "apn": "mms.yu.co.ke",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.yu.co.ke"
+      }
+    ]
+  },
+  {
+    "name": "Safaricom",
+    "ids": [
+      "63902"
+    ],
+    "apns": [
+      {
+        "name": "Safaricom (Prepaid)",
+        "apn": "safaricom",
+        "type": [
+          "internet"
+        ],
+        "username": "saf",
+        "password": "data"
+      },
+      {
+        "apn": "safaricom",
+        "type": [
+          "internet"
+        ],
+        "username": "web",
+        "password": "web"
+      },
+      {
+        "name": "Safaricom MMS",
+        "apn": "mms.safaricom.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.gprs.safaricom.com",
+        "mmsproxy": "172.22.2.38:8080",
+        "username": "saf",
+        "password": "data"
+      }
+    ]
+  },
+  {
+    "name": "yu (Econet)",
+    "ids": [
+      "63905"
+    ],
+    "apns": [
+      {
+        "apn": "internet.econet.co.ke",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "63907"
+    ],
+    "apns": [
+      {
+        "apn": "bew.orange.co.ke",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Beeline",
+    "ids": [
+      "43701"
+    ],
+    "apns": [
+      {
+        "apn": "internet.beeline.kg",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "MegaCom",
+    "ids": [
+      "43705"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "O!",
+    "ids": [
+      "43709"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Cellcard",
+    "ids": [
+      "45601"
+    ],
+    "apns": [
+      {
+        "apn": "cellcard",
+        "type": [
+          "internet"
+        ],
+        "username": "mobitel",
+        "password": "mobitel"
+      },
+      {
+        "name": "Mobitel MMS",
+        "apn": "internet",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.mobitel.si/servlets/mms",
+        "mmsproxy": "213.229.249.40:8080",
+        "username": "mobitel",
+        "password": "internet"
+      },
+      {
+        "name": "GPRS MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.mobitel.com.kh/mmsc",
+        "mmsproxy": "203.144.95.98:3130",
+        "username": "mobitel",
+        "password": "mobitel"
+      }
+    ]
+  },
+  {
+    "name": "Hello",
+    "ids": [
+      "45602"
+    ],
+    "apns": [
+      {
+        "apn": "hellowww",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Hellow MMS",
+        "apn": "hellomms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.iq2mobile.com",
+        "mmsproxy": "192.168.205.20:8088"
+      }
+    ]
+  },
+  {
+    "name": "qb",
+    "ids": [
+      "45604"
+    ],
+    "apns": [
+      {
+        "apn": "WAP",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Smart Mobile",
+    "ids": [
+      "45606"
+    ],
+    "apns": [
+      {
+        "apn": "smart",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Metfone",
+    "ids": [
+      "45608"
+    ],
+    "apns": [
+      {
+        "apn": "metfone",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Beeline",
+    "ids": [
+      "45609"
+    ],
+    "apns": [
+      {
+        "apn": "gprs.beeline.com.kh",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Mfone",
+    "ids": [
+      "45618"
+    ],
+    "apns": [
+      {
+        "apn": "Mfone",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "KT",
+    "ids": [
+      "45008"
+    ],
+    "apns": [
+      {
+        "name": "KT 3G",
+        "apn": "alwayson.ktfwing.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "KT LTE",
+        "apn": "lte.ktfwing.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "KT MMS",
+        "apn": "lte.ktfwing.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.ktfwing.com:9082"
+      }
+    ]
+  },
+  {
+    "name": "LG U+",
+    "ids": [
+      "45006"
+    ],
+    "apns": [
+      {
+        "apn": "internet.lguplus.co.kr",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "LG U+ MMS",
+        "apn": "internet.lguplus.co.kr",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://omammsc.uplus.co.kr:9084"
+      }
+    ]
+  },
+  {
+    "name": "SK Telecom",
+    "ids": [
+      "45005"
+    ],
+    "apns": [
+      {
+        "name": "SKT 3G",
+        "apn": "web.sktelecom.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "SKT LTE",
+        "apn": "lte.sktelecom.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "SKT MMS",
+        "apn": "lte.sktelecom.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://omms.nate.com:9082/oma_mms",
+        "mmsproxy": "smart.nate.com:9093"
+      }
+    ]
+  },
+  {
+    "name": "Zain",
+    "ids": [
+      "41902"
+    ],
+    "apns": [
+      {
+        "name": "Personal",
+        "apn": "pps",
+        "type": [
+          "internet"
+        ],
+        "username": "pps",
+        "password": "pps"
+      },
+      {
+        "name": "Corporate",
+        "apn": "apn01",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Wataniya",
+    "ids": [
+      "41903"
+    ],
+    "apns": [
+      {
+        "apn": "action.wataniya.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS Action",
+        "apn": "mms.wataniya.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://action.wataniya.com",
+        "mmsproxy": "194.126.53.64:8080"
+      }
+    ]
+  },
+  {
+    "name": "Viva",
+    "ids": [
+      "41904"
+    ],
+    "apns": [
+      {
+        "apn": "viva",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "viva",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://172.16.128.80:38090/was",
+        "mmsproxy": "172.16.128.228:8080"
+      }
+    ]
+  },
+  {
+    "name": "Beeline",
+    "ids": [
+      "40101"
+    ],
+    "apns": [
+      {
+        "apn": "internet.beeline.kz",
+        "type": [
+          "internet"
+        ],
+        "username": "@internet.beeline"
+      }
+    ]
+  },
+  {
+    "name": "K'CELL",
+    "ids": [
+      "40102"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "kcell mms",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://192.168.75.10:6001/MM1Servlet",
+        "mmsproxy": "195.47.255.15:8080"
+      }
+    ]
+  },
+  {
+    "name": "Activ",
+    "ids": [
+      "40102"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Tele2",
+    "ids": [
+      "40177"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Altel 4G",
+    "ids": [
+      "40177"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "ETL",
+    "ids": [
+      "45702"
+    ],
+    "apns": [
+      {
+        "apn": "etlnet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Lao Telecom",
+    "ids": [
+      "45701"
+    ],
+    "apns": [
+      {
+        "apn": "ltcnet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Unitel",
+    "ids": [
+      "45703"
+    ],
+    "apns": [
+      {
+        "name": "Unitel (2G)",
+        "apn": "startelecom",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Unitel (3G)",
+        "apn": "unitel3g",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Beeline (Tigo)",
+    "ids": [
+      "45708"
+    ],
+    "apns": [
+      {
+        "apn": "beelinenet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "MTC Touch",
+    "ids": [
+      "41503"
+    ],
+    "apns": [
+      {
+        "apn": "gprs.mtctouch.com.lb",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "mtctouch MMS",
+        "apn": "mms.mtctouch.com.lb",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms:8088/mms/",
+        "mmsproxy": "192.168.4.103:8080",
+        "username": "mtctouch"
+      }
+    ]
+  },
+  {
+    "name": "Datamobile",
+    "ids": [
+      "29505"
+    ],
+    "apns": [
+      {
+        "apn": "datamobile.ag",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Cable & Wireless",
+    "ids": [
+      "358110"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS Postpaid",
+        "apn": "multimedia",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc",
+        "mmsproxy": "10.20.5.34:8799"
+      }
+    ]
+  },
+  {
+    "name": "Airtel",
+    "ids": [
+      "41305"
+    ],
+    "apns": [
+      {
+        "apn": "www.wap.airtel.lk",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Dialog GSM",
+    "ids": [
+      "41302"
+    ],
+    "apns": [
+      {
+        "name": "Postpaid",
+        "apn": "www.dialogsl.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Prepaid",
+        "apn": "ppinternet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Unlimited Broadband",
+        "apn": "dialogbb",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Prepaid (Kitbb)",
+        "apn": "kitbb.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Dialog - Go MMS",
+        "apn": "www.dialogsl.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://192.168.122.130:3130/mmsc",
+        "mmsproxy": "192.168.122.2:8080"
+      },
+      {
+        "name": "Go MMS for KIT",
+        "apn": "ppwap",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.dialog.lk:3130/mmsc",
+        "mmsproxy": "192.168.122.2:8080"
+      }
+    ]
+  },
+  {
+    "name": "Hutch",
+    "ids": [
+      "41308"
+    ],
+    "apns": [
+      {
+        "apn": "htwap",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Mobitel",
+    "ids": [
+      "41301"
+    ],
+    "apns": [
+      {
+        "apn": "isp",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Tigo",
+    "ids": [
+      "41303"
+    ],
+    "apns": [
+      {
+        "apn": "wap",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Vodacom Lesotho",
+    "ids": [
+      "65101"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Bite",
+    "ids": [
+      "24602"
+    ],
+    "apns": [
+      {
+        "apn": "banga",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "BITE mms",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc/servlets/mms",
+        "mmsproxy": "192.168.150.2:8080",
+        "username": "mms@mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "TELE2 GPRS",
+    "ids": [
+      "24603"
+    ],
+    "apns": [
+      {
+        "apn": "internet.tele2.lt",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Tele2 MMS",
+        "apn": "mms.tele2.lt",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.tele2.lt",
+        "mmsproxy": "193.12.40.29:8080",
+        "username": "wap",
+        "password": "wap"
+      },
+      {
+        "name": "Tele2 MMS",
+        "apn": "mms.tele2.lv",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.tele2.lv",
+        "mmsproxy": "193.12.40.38:8080",
+        "username": "wap",
+        "password": "wap"
+      }
+    ]
+  },
+  {
+    "name": "Omnitel (contract)",
+    "ids": [
+      "24601"
+    ],
+    "apns": [
+      {
+        "name": "Contract",
+        "apn": "gprs.omnitel.net",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "No contract",
+        "apn": "gprs.startas.lt",
+        "type": [
+          "internet"
+        ],
+        "username": "omni",
+        "password": "omni"
+      },
+      {
+        "name": "Omnitel MMS",
+        "apn": "gprs.mms.lt",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.omnitel.net:8002/",
+        "mmsproxy": "194.176.32.149:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "LUXGSM",
+    "ids": [
+      "27001"
+    ],
+    "apns": [
+      {
+        "apn": "web.pt.lu",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Luxgsm MMS",
+        "apn": "mms.pt.lu",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.pt.lu",
+        "mmsproxy": "194.154.192.88:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Tango",
+    "ids": [
+      "27077"
+    ],
+    "apns": [
+      {
+        "name": "hspa",
+        "apn": "hspa",
+        "type": [
+          "internet"
+        ],
+        "username": "tango",
+        "password": "tango"
+      },
+      {
+        "name": "internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "tango",
+        "password": "tango"
+      },
+      {
+        "name": "Tango MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.tango.lu/",
+        "mmsproxy": "212.66.75.3:8080",
+        "username": "tango",
+        "password": "tango"
+      },
+      {
+        "name": "Tango MMS",
+        "apn": "mms.li",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "mms.tele2.li",
+        "mmsproxy": "212.66.75.9:8080"
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "27099"
+    ],
+    "apns": [
+      {
+        "apn": "orange.lu",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "VOXmobile",
+    "ids": [
+      "27099"
+    ],
+    "apns": [
+      {
+        "apn": "vox.lu",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "VOX mms GPRS",
+        "apn": "vox.lu",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.vox.lu",
+        "mmsproxy": "proxy.vox.lu:8080"
+      }
+    ]
+  },
+  {
+    "name": "LMT",
+    "ids": [
+      "24701"
+    ],
+    "apns": [
+      {
+        "apn": "internet.lmt.lv",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "O!Karte internet",
+        "apn": "open.lmt.lv",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "O!Karte",
+        "apn": "okarte.lmt.lv",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "LMT MMS",
+        "apn": "mms.lmt.lv",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.lmt.lv/mmsc",
+        "username": "lmt",
+        "password": "lmt"
+      }
+    ]
+  },
+  {
+    "name": "Tele2",
+    "ids": [
+      "24702"
+    ],
+    "apns": [
+      {
+        "name": "Regular",
+        "apn": "internet.tele2.lv",
+        "type": [
+          "internet"
+        ],
+        "username": "gprs",
+        "password": "internet"
+      },
+      {
+        "name": "Mobile Internet",
+        "apn": "mobileinternet.tele2.lv",
+        "type": [
+          "internet"
+        ],
+        "username": "wap",
+        "password": "wap"
+      },
+      {
+        "name": "Zelta Zivtina",
+        "apn": "data.tele2.lv",
+        "type": [
+          "internet"
+        ],
+        "username": "wap",
+        "password": "wap"
+      }
+    ]
+  },
+  {
+    "name": "Bite",
+    "ids": [
+      "24705"
+    ],
+    "apns": [
+      {
+        "name": "Bite plus",
+        "apn": "wap",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Prepaid/Contract",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Ittissalat Al Maghrib (IAM)",
+    "ids": [
+      "60401"
+    ],
+    "apns": [
+      {
+        "name": "Abonnement",
+        "apn": "www.iamgprs1.ma",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Pre-payé",
+        "apn": "www.iamgprs2.ma",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMSIAM",
+        "apn": "Mmsiam",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms:8002/",
+        "mmsproxy": "10.16.35.50:8080"
+      }
+    ]
+  },
+  {
+    "name": "WANA",
+    "ids": [
+      "60402"
+    ],
+    "apns": [
+      {
+        "name": "INWI",
+        "apn": "www.wana.ma",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "mms.wana.ma",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.wana.ma:38090",
+        "mmsproxy": "10.86.0.10:8080"
+      }
+    ]
+  },
+  {
+    "name": "Moldcell",
+    "ids": [
+      "25902"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "gprs",
+        "password": "gprs"
+      },
+      {
+        "name": "Moldcell MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.moldcell.md/cmmsc/post",
+        "mmsproxy": "10.0.10.10:9401"
+      }
+    ]
+  },
+  {
+    "name": "Unité",
+    "ids": [
+      "25905"
+    ],
+    "apns": [
+      {
+        "name": "Internet cu abonament",
+        "apn": "internet.unite.md",
+        "type": [
+          "internet"
+        ],
+        "username": "gprs",
+        "password": "gprs"
+      },
+      {
+        "name": "Internet fără abonament",
+        "apn": "internet3g.unite.md",
+        "type": [
+          "internet"
+        ],
+        "username": "gprs",
+        "password": "gprs"
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "25901"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "gprs",
+        "password": "gprs"
+      }
+    ]
+  },
+  {
+    "name": "ProMonte GSM",
+    "ids": [
+      "29701"
+    ],
+    "apns": [
+      {
+        "apn": "gprs.promonte.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "ProMMS",
+        "apn": "mms.promonte.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mm.vor.promonte.com",
+        "mmsproxy": "192.168.246.5:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "T-Mobile",
+    "ids": [
+      "29702"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Broadband",
+        "apn": "tmcg-data",
+        "type": [
+          "internet"
+        ],
+        "username": "38267",
+        "password": "38267"
+      },
+      {
+        "name": "GPRS",
+        "apn": "tmcg-nw",
+        "type": [
+          "internet"
+        ],
+        "username": "38267",
+        "password": "38267"
+      },
+      {
+        "name": "Postpaid (old)",
+        "apn": "internet-postpaid",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Prepaid (old)",
+        "apn": "internet-prepaid",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "m:tel",
+    "ids": [
+      "29703"
+    ],
+    "apns": [
+      {
+        "apn": "gprsinternet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "mtelmms",
+        "apn": "mtelmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsmtel.com/mms/wapenc",
+        "mmsproxy": "172.17.85.131:8080",
+        "username": "mms",
+        "password": "068"
+      }
+    ]
+  },
+  {
+    "name": "Airtel",
+    "ids": [
+      "64601"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "64602"
+    ],
+    "apns": [
+      {
+        "apn": "orangeworld",
+        "type": [
+          "internet"
+        ],
+        "username": "world",
+        "password": "orange"
+      }
+    ]
+  },
+  {
+    "name": "Telma",
+    "ids": [
+      "64604"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Malitel",
+    "ids": [
+      "61001"
+    ],
+    "apns": [
+      {
+        "name": "3G+",
+        "apn": "web.malitel3.ml",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "61002"
+    ],
+    "apns": [
+      {
+        "name": "Internet Every Where",
+        "apn": "iew",
+        "type": [
+          "internet"
+        ],
+        "username": "iew",
+        "password": "iew"
+      },
+      {
+        "name": "Internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      }
+    ]
+  },
+  {
+    "name": "MPT",
+    "ids": [
+      "41401"
+    ],
+    "apns": [
+      {
+        "name": "MPTNET",
+        "apn": "mptnet",
+        "type": [
+          "internet"
+        ],
+        "username": "mptnet",
+        "password": "mptnet"
+      }
+    ]
+  },
+  {
+    "name": "Telenor",
+    "ids": [
+      "41406"
+    ],
+    "apns": [
+      {
+        "name": "Telenor",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      }
+    ]
+  },
+  {
+    "name": "Ooredoo",
+    "ids": [
+      "41405"
+    ],
+    "apns": [
+      {
+        "name": "Ooredoo",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      }
+    ]
+  },
+  {
+    "name": "MobiCom",
+    "ids": [
+      "42899"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS MobiCom",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms",
+        "mmsproxy": "10.10.10.10:8080"
+      }
+    ]
+  },
+  {
+    "name": "3 / Hutchison",
+    "ids": [
+      "45503",
+      "45505"
+    ],
+    "apns": [
+      {
+        "apn": "web.hutchisonmacau.com",
+        "type": [
+          "internet"
+        ],
+        "username": "hutchison",
+        "password": "1234"
+      },
+      {
+        "name": "HutchisonMMS",
+        "apn": "mms.hutchisonmacau.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.30.15.51:10021/mmsc",
+        "mmsproxy": "10.30.15.53:8080",
+        "username": "hutchison",
+        "password": "1234"
+      }
+    ]
+  },
+  {
+    "name": "CTM",
+    "ids": [
+      "45501",
+      "45504"
+    ],
+    "apns": [
+      {
+        "apn": "ctm-mobile",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "CTMMMS",
+        "apn": "ctmmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.wap.ctm.net:8002",
+        "mmsproxy": "192.168.99.3:8080"
+      }
+    ]
+  },
+  {
+    "name": "T-Mobile",
+    "ids": [
+      "29401"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      }
+    ]
+  },
+  {
+    "name": "One",
+    "ids": [
+      "29402"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "datacard",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Cosmofon MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://195.167.65.220:8002",
+        "mmsproxy": "10.10.10.20:8080"
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "29403"
+    ],
+    "apns": [
+      {
+        "apn": "vipoperator",
+        "type": [
+          "internet"
+        ],
+        "username": "vipoperator",
+        "password": "vipoperator"
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "29404"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.mk",
+        "type": [
+          "internet"
+        ],
+        "username": "lmde",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "GO Mobile",
+    "ids": [
+      "27821"
+    ],
+    "apns": [
+      {
+        "name": "Postpaid",
+        "apn": "gosurfing",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Prepaid",
+        "apn": "rtgsurfing",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "go mms",
+        "apn": "gomms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc",
+        "mmsproxy": "10.20.20.129:8080"
+      }
+    ]
+  },
+  {
+    "name": "Melita",
+    "ids": [
+      "27877"
+    ],
+    "apns": [
+      {
+        "name": "Melita Connector",
+        "apn": "web.melita",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "27801"
+    ],
+    "apns": [
+      {
+        "apn": "Internet",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      }
+    ]
+  },
+  {
+    "name": "Emtel",
+    "ids": [
+      "61710"
+    ],
+    "apns": [
+      {
+        "apn": "WEB",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Dhiraagu",
+    "ids": [
+      "47201"
+    ],
+    "apns": [
+      {
+        "apn": "internet.dhimobile",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "DhiMMS",
+        "apn": "mms.dhimobile",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.dhimobile.com.mv",
+        "mmsproxy": "172.24.97.4:8080"
+      }
+    ]
+  },
+  {
+    "name": "Wataniya",
+    "ids": [
+      "47202"
+    ],
+    "apns": [
+      {
+        "apn": "WataniyaNet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Airtel MW",
+    "ids": [
+      "65010"
+    ],
+    "apns": [
+      {
+        "name": "All plans",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "TNM",
+    "ids": [
+      "65001"
+    ],
+    "apns": [
+      {
+        "apn": "Internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Telcel",
+    "ids": [
+      "33402"
+    ],
+    "apns": [
+      {
+        "apn": "internet.itelcel.com",
+        "type": [
+          "internet"
+        ],
+        "username": "webgprs",
+        "password": "webgprs2002"
+      },
+      {
+        "name": "Mensajes Multimedia",
+        "apn": "mms.itelcel.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.itelcel.com/servlets/mms",
+        "mmsproxy": "148.233.151.240:8080",
+        "username": "mmsgprs",
+        "password": "mmsgprs2003"
+      }
+    ]
+  },
+  {
+    "name": "Movistar",
+    "ids": [
+      "33403"
+    ],
+    "apns": [
+      {
+        "apn": "internet.movistar.mx",
+        "type": [
+          "internet"
+        ],
+        "username": "movistar",
+        "password": "movistar"
+      }
+    ]
+  },
+  {
+    "name": "DiGi",
+    "ids": [
+      "50216"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Internet",
+        "apn": "diginet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Broadband",
+        "apn": "3gdgnet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "DiGi MMS",
+        "apn": "digimms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.digi.com.my/servlets/mms",
+        "mmsproxy": "203.92.128.160:80"
+      }
+    ]
+  },
+  {
+    "name": "Maxis",
+    "ids": [
+      "50212",
+      "50217"
+    ],
+    "apns": [
+      {
+        "name": "Broadband",
+        "apn": "maxisbb",
+        "type": [
+          "internet"
+        ],
+        "username": "maxis",
+        "password": "wap"
+      },
+      {
+        "name": "GPRS",
+        "apn": "net",
+        "type": [
+          "internet"
+        ],
+        "username": "maxis",
+        "password": "net"
+      },
+      {
+        "name": "3G (handsets)",
+        "apn": "unet",
+        "type": [
+          "internet"
+        ],
+        "username": "maxis",
+        "password": "wap"
+      },
+      {
+        "name": "Maxis 3G MMS",
+        "apn": "unet",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://172.16.74.100:10021/mmsc",
+        "mmsproxy": "202.75.133.49:80",
+        "username": "maxis",
+        "password": "wap"
+      }
+    ]
+  },
+  {
+    "name": "Celcom",
+    "ids": [
+      "50213",
+      "50219"
+    ],
+    "apns": [
+      {
+        "name": "GPRS",
+        "apn": "celcom.net.my",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Celcom 3G",
+        "apn": "celcom3g",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Celcom 3G MMS",
+        "apn": "celcom3g",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.celcom.net.my",
+        "mmsproxy": "10.128.1.242:8080"
+      }
+    ]
+  },
+  {
+    "name": "MCel",
+    "ids": [
+      "64301"
+    ],
+    "apns": [
+      {
+        "apn": "isp.mcel.mz",
+        "type": [
+          "internet"
+        ],
+        "username": "guest",
+        "password": "guest"
+      },
+      {
+        "name": "mCel MMS",
+        "apn": "mms.mcel.mz",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mcelmms",
+        "mmsproxy": "10.1.4.35:8080"
+      }
+    ]
+  },
+  {
+    "name": "Movitel",
+    "ids": [
+      "64303"
+    ],
+    "apns": [
+      {
+        "apn": "default",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Vodacom",
+    "ids": [
+      "64304"
+    ],
+    "apns": [
+      {
+        "name": "Contract / Prepaid",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "MTC",
+    "ids": [
+      "64901"
+    ],
+    "apns": [
+      {
+        "name": "Tango",
+        "apn": "ppsinternet",
+        "type": [
+          "internet"
+        ],
+        "username": "ppsuser",
+        "password": "ppsuser"
+      },
+      {
+        "name": "Contract",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Leo",
+    "ids": [
+      "64903"
+    ],
+    "apns": [
+      {
+        "name": "Leo",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Cell One MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "mms.cellone.com.na",
+        "mmsproxy": "41.223.80.10:8080",
+        "username": "cellone",
+        "password": "cellone"
+      }
+    ]
+  },
+  {
+    "name": "Airtel NG",
+    "ids": [
+      "62120",
+      "62180"
+    ],
+    "apns": [
+      {
+        "apn": "internet.ng.airtel.com.ng",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      }
+    ]
+  },
+  {
+    "name": "MTN",
+    "ids": [
+      "62130",
+      "62160"
+    ],
+    "apns": [
+      {
+        "apn": "web.gprs.mtnnigeria.net",
+        "type": [
+          "internet"
+        ],
+        "username": "web",
+        "password": "web"
+      }
+    ]
+  },
+  {
+    "name": "Glo Mobile",
+    "ids": [
+      "62150",
+      "62170"
+    ],
+    "apns": [
+      {
+        "name": "Pay as You Go",
+        "apn": "glosecure",
+        "type": [
+          "internet"
+        ],
+        "username": "gprs",
+        "password": "gprs"
+      },
+      {
+        "name": "Glo 3G Packs",
+        "apn": "gloflat",
+        "type": [
+          "internet"
+        ],
+        "username": "flat",
+        "password": "flat"
+      }
+    ]
+  },
+  {
+    "name": "Etisalat",
+    "ids": [
+      "62190"
+    ],
+    "apns": [
+      {
+        "name": "Etisalat Internet",
+        "apn": "etisalat",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Claro",
+    "ids": [
+      "71021",
+      "71073"
+    ],
+    "apns": [
+      {
+        "name": "WAP",
+        "apn": "wap.emovil",
+        "type": [
+          "wap"
+        ],
+        "username": "wapemovil",
+        "password": "wapemovil"
+      },
+      {
+        "name": "Web",
+        "apn": "web.emovil",
+        "type": [
+          "internet"
+        ],
+        "username": "webemovil",
+        "password": "webemovil"
+      },
+      {
+        "name": "Web (Alo pcs)",
+        "apn": "internet.ideasalo.ni",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      },
+      {
+        "name": "WAP (Alo pcs)",
+        "apn": "wap.ideasalo.ni",
+        "type": [
+          "wap"
+        ],
+        "username": "wap",
+        "password": "wap"
+      }
+    ]
+  },
+  {
+    "name": "Movistar",
+    "ids": [
+      "71030"
+    ],
+    "apns": [
+      {
+        "apn": "internet.movistar.ni",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      }
+    ]
+  },
+  {
+    "name": "Hi",
+    "ids": [
+      "20408"
+    ],
+    "apns": [
+      {
+        "apn": "portalmmm.nl",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "KPN MMS",
+        "apn": "portalmmm.nl",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mp.mobiel.kpn/mmsc",
+        "mmsproxy": "10.10.100.20:5080"
+      }
+    ]
+  },
+  {
+    "name": "Lebara",
+    "ids": [
+      "20412"
+    ],
+    "apns": [
+      {
+        "apn": "multimedia.lebara.nl",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Telfort MMS",
+        "apn": "internet",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms",
+        "mmsproxy": "193.113.200.195:8080"
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "20409"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.nl",
+        "type": [
+          "internet"
+        ],
+        "username": "lmnl",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "KPN NL",
+    "ids": [
+      "20408"
+    ],
+    "apns": [
+      {
+        "name": "KPN Prepaid Mobiel Internet",
+        "apn": "prepaidinternet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "KPN 3G/2G LTE Mobiel Internet",
+        "apn": "fastinternet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "KPN",
+        "password": "gprs"
+      },
+      {
+        "name": "KPN 4G LTE Mobiel Internet",
+        "apn": "KPN4G.nl",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "KPN Mobiel Internet",
+        "apn": "portalmmm.nl",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "KPN MMS",
+        "apn": "portalmmm.nl",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mp.mobiel.kpn/mmsc",
+        "mmsproxy": "10.10.100.20:5080"
+      }
+    ]
+  },
+  {
+    "name": "MEDIONmobile",
+    "ids": [
+      "20408",
+      "20410"
+    ],
+    "apns": [
+      {
+        "name": "Aldi Talk Mobiel Prepaid Internet",
+        "apn": "portalmmm.nl",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Telfort",
+    "ids": [
+      "20412"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "telfortnl"
+      }
+    ]
+  },
+  {
+    "name": "T-Mobile",
+    "ids": [
+      "20416"
+    ],
+    "apns": [
+      {
+        "name": "T-Mobile Internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "T-Mobile NL",
+        "apn": "smartsites.t-mobile",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "T-Mobile NL MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://t-mobilemms",
+        "mmsproxy": "10.10.10.11:8080",
+        "username": "tmobilemms",
+        "password": "tmobilemms"
+      }
+    ]
+  },
+  {
+    "name": "Ben",
+    "ids": [
+      "20416"
+    ],
+    "apns": [
+      {
+        "name": "Ben internet (prepaid)",
+        "apn": "basic.internet.ben.data",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Ben internet",
+        "apn": "internet.ben",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Ben MMS",
+        "apn": "mms.ben",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://benmms",
+        "mmsproxy": "10.10.10.11:8080"
+      }
+    ]
+  },
+  {
+    "name": "Simpel",
+    "ids": [
+      "20416"
+    ],
+    "apns": [
+      {
+        "name": "Simpel",
+        "apn": "internet.access.nl",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "20420"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "orange",
+        "password": "orange"
+      }
+    ]
+  },
+  {
+    "name": "Tele2",
+    "ids": [
+      "20402"
+    ],
+    "apns": [
+      {
+        "apn": "data.tele2.nl",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "20404"
+    ],
+    "apns": [
+      {
+        "name": "Non-business",
+        "apn": "live.vodafone.com",
+        "type": [
+          "internet"
+        ],
+        "username": "vodafone",
+        "password": "vodafone"
+      },
+      {
+        "name": "Business",
+        "apn": "office.vodafone.nl",
+        "type": [
+          "internet"
+        ],
+        "username": "vodafone",
+        "password": "vodafone"
+      },
+      {
+        "name": "M2M",
+        "apn": "m2m.global.vodafone.nl",
+        "type": [
+          "internet"
+        ],
+        "authentication": "pap",
+        "username": "web",
+        "password": "web"
+      }
+    ]
+  },
+  {
+    "name": "Galaxy",
+    "ids": [
+      "20408"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Netcom",
+    "ids": [
+      "24202"
+    ],
+    "apns": [
+      {
+        "apn": "internet.netcom.no",
+        "type": [
+          "internet"
+        ],
+        "username": "netcom",
+        "password": "netcom"
+      },
+      {
+        "name": "NetCom mms",
+        "apn": "mms.netcom.no",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms/",
+        "mmsproxy": "212.169.66.4:8080",
+        "username": "mms",
+        "password": "netcom"
+      }
+    ]
+  },
+  {
+    "name": "Chess",
+    "ids": [
+      "24202"
+    ],
+    "apns": [
+      {
+        "apn": "netcom",
+        "type": [
+          "internet"
+        ],
+        "username": "chess",
+        "password": "chess"
+      },
+      {
+        "name": "Chess MMS",
+        "apn": "mms.netcom.no",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms/",
+        "mmsproxy": "212.169.66.4:8080",
+        "username": "chess",
+        "password": "chess"
+      }
+    ]
+  },
+  {
+    "name": "Telenor",
+    "ids": [
+      "24201"
+    ],
+    "apns": [
+      {
+        "name": "Telenor",
+        "apn": "telenor.smart",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Telenor MMS",
+        "apn": "telenor.smart",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc",
+        "mmsproxy": "mms-proxy.telenor.no:8080"
+      },
+      {
+        "name": "Ventelo MMS",
+        "apn": "mms.ventelo.no",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc/",
+        "mmsproxy": "10.10.10.11:8080",
+        "username": "ventelo",
+        "password": "1111"
+      }
+    ]
+  },
+  {
+    "name": "TDC",
+    "ids": [
+      "24208"
+    ],
+    "apns": [
+      {
+        "apn": "internet.no",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Network Norway",
+    "ids": [
+      "24205"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "NWN MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.nwn.no",
+        "mmsproxy": "89.254.65.20:80"
+      }
+    ]
+  },
+  {
+    "name": "OneCall",
+    "ids": [
+      "24205"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "MyCall",
+    "ids": [
+      "24205"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Telipol",
+    "ids": [
+      "24205"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Ventelo",
+    "ids": [
+      "24207"
+    ],
+    "apns": [
+      {
+        "apn": "internet.ventelo.no",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Ludo Mobil",
+    "ids": [
+      "24207"
+    ],
+    "apns": [
+      {
+        "apn": "internet.ventelo.no",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Tele2",
+    "ids": [
+      "24202",
+      "24204"
+    ],
+    "apns": [
+      {
+        "name": "Mobilt internet",
+        "apn": "internet.tele2.no",
+        "type": [
+          "wap"
+        ]
+      },
+      {
+        "name": "Mobilt bredbånd",
+        "apn": "mobileinternet.tele2.no",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Phonero",
+    "ids": [
+      "24201"
+    ],
+    "apns": [
+      {
+        "apn": "internet.phonero.no",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "24223"
+    ],
+    "apns": [
+      {
+        "apn": "data.lyca-mobile.no",
+        "type": [
+          "internet"
+        ],
+        "username": "lmno",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "Nepal Telecom",
+    "ids": [
+      "42901"
+    ],
+    "apns": [
+      {
+        "apn": "ntnet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Mero Mobile",
+    "ids": [
+      "42902"
+    ],
+    "apns": [
+      {
+        "apn": "mero",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Telecom New Zealand",
+    "ids": [
+      "53005"
+    ],
+    "apns": [
+      {
+        "name": "XT mobile (WAP)",
+        "apn": "wap.telecom.co.nz",
+        "type": [
+          "wap"
+        ]
+      },
+      {
+        "name": "XT mobile (Internet with Firewall)",
+        "apn": "internet.telecom.co.nz",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "XT mobile (Direct Internet)",
+        "apn": "direct.telecom.co.nz",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "XT mobile (One Office/Remote Office)",
+        "apn": "oa.telecom.co.nz",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "TelecomMMS",
+        "apn": "wap.telecom.co.nz",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://lsmmsc.xtra.co.nz",
+        "mmsproxy": "210.55.11.73:8080"
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "53001"
+    ],
+    "apns": [
+      {
+        "name": "WAP",
+        "apn": "live.vodafone.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Contract / Prepaid (Restricted)",
+        "apn": "www.vodafone.net.nz",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Unrestricted (public)",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "2-Degrees",
+    "ids": [
+      "53024"
+    ],
+    "apns": [
+      {
+        "name": "Broadband",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "mms",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.2degrees.net.nz:48090",
+        "mmsproxy": "118.148.1.118:8080"
+      }
+    ]
+  },
+  {
+    "name": "Oman Mobile",
+    "ids": [
+      "42202"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Broadband",
+        "apn": "taif",
+        "type": [
+          "internet"
+        ],
+        "username": "taif",
+        "password": "taif"
+      },
+      {
+        "name": "Internet (old)",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Nawras",
+    "ids": [
+      "42203"
+    ],
+    "apns": [
+      {
+        "apn": "isp.nawras.com.om",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Nawras MMS",
+        "apn": "mms.nawras.com.om",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.128.240.16/servlets/mms",
+        "mmsproxy": "10.128.240.19:8080",
+        "username": "test",
+        "password": "test"
+      }
+    ]
+  },
+  {
+    "name": "Cable and Wireless",
+    "ids": [
+      "71401"
+    ],
+    "apns": [
+      {
+        "apn": "apn01.cwpanama.com.pa",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "apn02.cwpanama.com.pa",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.zonamovil.com.pa",
+        "mmsproxy": "172.25.3.5:8080"
+      }
+    ]
+  },
+  {
+    "name": "Movistar",
+    "ids": [
+      "71402"
+    ],
+    "apns": [
+      {
+        "apn": "internet.movistar.pa",
+        "type": [
+          "internet"
+        ],
+        "username": "movistarpa",
+        "password": "movistarpa"
+      }
+    ]
+  },
+  {
+    "name": "Claro",
+    "ids": [
+      "71610"
+    ],
+    "apns": [
+      {
+        "apn": "tim.pe",
+        "type": [
+          "internet"
+        ],
+        "username": "tim",
+        "password": "tulibertad"
+      },
+      {
+        "name": "Internet Móvil Prepago",
+        "apn": "ba.amx",
+        "type": [
+          "internet"
+        ],
+        "username": "amx",
+        "password": "amx"
+      }
+    ]
+  },
+  {
+    "name": "Movistar",
+    "ids": [
+      "71606"
+    ],
+    "apns": [
+      {
+        "apn": "movistar.pe",
+        "type": [
+          "internet"
+        ],
+        "username": "movistar@datos",
+        "password": "movistar"
+      }
+    ]
+  },
+  {
+    "name": "Nextel",
+    "ids": [
+      "71607"
+    ],
+    "apns": [
+      {
+        "apn": "datacard.nextel.com.pe",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Vini MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.vini.pf/mmsc",
+        "mmsproxy": "172.20.10.16:9201"
+      }
+    ]
+  },
+  {
+    "name": "Vini",
+    "ids": [
+      "54720"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Digicel",
+    "ids": [
+      "53703"
+    ],
+    "apns": [
+      {
+        "name": "Prepaid",
+        "apn": "internet.digicelpng.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Globe Telecom",
+    "ids": [
+      "51502"
+    ],
+    "apns": [
+      {
+        "name": "Postpaid",
+        "apn": "internet.globe.com.ph",
+        "type": [
+          "internet"
+        ],
+        "username": "globe",
+        "password": "globe"
+      },
+      {
+        "name": "Prepaid",
+        "apn": "http.globe.com.ph",
+        "type": [
+          "internet"
+        ],
+        "username": "globe",
+        "password": "globe"
+      },
+      {
+        "name": "WAP",
+        "apn": "www.globe.com.ph",
+        "type": [
+          "internet"
+        ],
+        "username": "globe",
+        "password": "globe"
+      },
+      {
+        "name": "myGlobe MMS",
+        "apn": "mms.globe.com.ph",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://192.40.100.22:10021/mmsc",
+        "mmsproxy": "192.40.100.20:8080"
+      }
+    ]
+  },
+  {
+    "name": "Smart",
+    "ids": [
+      "51503"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "witsductoor",
+        "password": "banonoy"
+      },
+      {
+        "name": "SmartMMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.102.61.238:8002",
+        "mmsproxy": "10.102.61.46:8080"
+      }
+    ]
+  },
+  {
+    "name": "Digitel (Sun Cellular)",
+    "ids": [
+      "51505"
+    ],
+    "apns": [
+      {
+        "apn": "minternet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Sun MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmscenter.suncellular.com.ph",
+        "mmsproxy": "202.138.159.78:8080"
+      }
+    ]
+  },
+  {
+    "name": "Mobilink",
+    "ids": [
+      "41001"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "connect.mobilinkworld.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Jazz",
+        "apn": "jazzconnect.mobilinkworld.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Telenor",
+    "ids": [
+      "41006"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "telenor",
+        "password": "telenor"
+      }
+    ]
+  },
+  {
+    "name": "Ufone",
+    "ids": [
+      "41003"
+    ],
+    "apns": [
+      {
+        "apn": "ufone.internet",
+        "type": [
+          "internet"
+        ],
+        "username": "ufone",
+        "password": "ufone"
+      },
+      {
+        "name": "Ufone MMS",
+        "apn": "ufone.mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://www.ufonemms.com:80",
+        "mmsproxy": "172.16.13.27:8080",
+        "username": "ufone",
+        "password": "ufone"
+      }
+    ]
+  },
+  {
+    "name": "Warid",
+    "ids": [
+      "41007"
+    ],
+    "apns": [
+      {
+        "apn": "warid",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "ZONG MMS",
+        "apn": "zongmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.81.6.11:8080",
+        "mmsproxy": "10.81.6.33:8000"
+      }
+    ]
+  },
+  {
+    "name": "ZONG",
+    "ids": [
+      "41004"
+    ],
+    "apns": [
+      {
+        "apn": "zonginternet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "T-Mobile",
+    "ids": [
+      "26002"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms/servlets/mms",
+        "mmsproxy": "213.158.194.226:8080"
+      }
+    ]
+  },
+  {
+    "name": "Play",
+    "ids": [
+      "26006"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.play.pl/mms/wapenc"
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "26003"
+    ],
+    "apns": [
+      {
+        "name": "Standard access",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      },
+      {
+        "name": "Standard access (IPv6)",
+        "apn": "internetipv6",
+        "type": [
+          "internet"
+        ],
+        "username": "internetipv6",
+        "password": "internetipv6"
+      },
+      {
+        "name": "External dynamic IP address (requires activation)",
+        "apn": "vpn",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "External static IP address (requires activation)",
+        "apn": "vpn.static.pl",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.orange.pl",
+        "mmsproxy": "192.168.6.104:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Plus",
+    "ids": [
+      "26001"
+    ],
+    "apns": [
+      {
+        "name": "Standard access",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      },
+      {
+        "name": "External dynamic IP address (requires activation)",
+        "apn": "pro",
+        "type": [
+          "internet"
+        ],
+        "username": "plusgsm",
+        "password": "plusgsm"
+      },
+      {
+        "name": "External static IP address (requires activation)",
+        "apn": "m2m",
+        "type": [
+          "internet"
+        ],
+        "username": "plusgsm",
+        "password": "plusgsm"
+      },
+      {
+        "name": "iPlus optimizer with data compression",
+        "apn": "optimizer",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.plusgsm.pl:8002",
+        "mmsproxy": "212.2.96.16:8080"
+      }
+    ]
+  },
+  {
+    "name": "Cyfrowy Polsat",
+    "ids": [
+      "26012"
+    ],
+    "apns": [
+      {
+        "apn": "multi.internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "aero2",
+    "ids": [
+      "26017"
+    ],
+    "apns": [
+      {
+        "apn": "darmowy",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Multimo",
+    "ids": [
+      "26003"
+    ],
+    "apns": [
+      {
+        "name": "Default APN",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      },
+      {
+        "name": "APN: mni.internet",
+        "apn": "mni.internet",
+        "type": [
+          "internet"
+        ],
+        "username": "mni.internet"
+      },
+      {
+        "name": "APN: telogic.internet",
+        "apn": "telogic.internet",
+        "type": [
+          "internet"
+        ],
+        "username": "telogic.internet"
+      }
+    ]
+  },
+  {
+    "name": "Heyah",
+    "ids": [
+      "26002"
+    ],
+    "apns": [
+      {
+        "name": "heyah.pl",
+        "apn": "heyah.pl",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "heyahmms",
+        "apn": "heyahmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.heyah.pl/servlets/mms",
+        "mmsproxy": "213.158.194.226:8080",
+        "username": "heyah",
+        "password": "heyah"
+      },
+      {
+        "name": "mms",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms/servlets/mms",
+        "mmsproxy": "213.158.194.226:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Netia",
+    "ids": [
+      "26006"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Vectra",
+    "ids": [
+      "26006"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "INEA",
+    "ids": [
+      "26003"
+    ],
+    "apns": [
+      {
+        "apn": "telogic.internet",
+        "type": [
+          "internet"
+        ],
+        "username": "internet"
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "26009"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.pl",
+        "type": [
+          "internet"
+        ],
+        "username": "lmpl",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "nju mobile",
+    "ids": [
+      "26003"
+    ],
+    "apns": [
+      {
+        "name": "Standard access",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      },
+      {
+        "name": "Standard access (IPv6)",
+        "apn": "internetipv6",
+        "type": [
+          "internet"
+        ],
+        "username": "internetipv6",
+        "password": "internetipv6"
+      },
+      {
+        "name": "MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.njumobile.pl",
+        "mmsproxy": "192.168.6.104:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Virgin Mobile",
+    "ids": [
+      "26002",
+      "26006"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "virgin-internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "virgin-mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.virginpol.jsc",
+        "mmsproxy": "wap.virginpol.jsc:8080"
+      }
+    ]
+  },
+  {
+    "name": "Kanguru",
+    "ids": [
+      "26803"
+    ],
+    "apns": [
+      {
+        "name": "Portable",
+        "apn": "kanguru-portatil",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Tempo (Prepaid)",
+        "apn": "kanguru-tempo",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Fixo",
+        "apn": "kangurufixo",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Optimus MMS",
+        "apn": "umts",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc:10021/mmsc",
+        "mmsproxy": "62.169.66.5:8799"
+      }
+    ]
+  },
+  {
+    "name": "Clix",
+    "ids": [
+      "26803"
+    ],
+    "apns": [
+      {
+        "apn": "clixinternetmovel",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Optimus",
+    "ids": [
+      "26803"
+    ],
+    "apns": [
+      {
+        "name": "3G",
+        "apn": "umts",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "GPRS",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "26804"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.pt",
+        "type": [
+          "internet"
+        ],
+        "username": "lmpt",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "TMN",
+    "ids": [
+      "26806"
+    ],
+    "apns": [
+      {
+        "name": "Tmn Internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "tmn",
+        "password": "tmn"
+      },
+      {
+        "name": "MMSgprs",
+        "apn": "mmsc.tmn.pt",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc/",
+        "mmsproxy": "10.111.2.16:8080",
+        "username": "tmn",
+        "password": "tmnnet"
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "26801"
+    ],
+    "apns": [
+      {
+        "apn": "internet.vodafone.pt",
+        "type": [
+          "internet"
+        ],
+        "username": "vodafone",
+        "password": "vodafone"
+      },
+      {
+        "name": "Vodafone Internet",
+        "apn": "net2.vodafone.pt",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "ZON",
+    "ids": [
+      "26801"
+    ],
+    "apns": [
+      {
+        "name": "Dados Móveis",
+        "apn": "internet.zon.pt",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "ZON MMS",
+        "apn": "vas.zon.pt",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms/servlets/mms",
+        "mmsproxy": "213.30.27.63:8799",
+        "username": "vas",
+        "password": "vas"
+      }
+    ]
+  },
+  {
+    "name": "VOX",
+    "ids": [
+      "74401"
+    ],
+    "apns": [
+      {
+        "apn": "vox.wap",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "e-magen",
+        "apn": "vox.mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http:/mms.vox.com.py/mmsc",
+        "mmsproxy": "172.24.97.29:8080"
+      }
+    ]
+  },
+  {
+    "name": "Personal",
+    "ids": [
+      "74405"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Tigo",
+    "ids": [
+      "74404"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "internet.tigo.py",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Broadband",
+        "apn": "broadband.tigo.py",
+        "type": [
+          "internet"
+        ],
+        "username": "tigo",
+        "password": "tigo"
+      }
+    ]
+  },
+  {
+    "name": "Claro",
+    "ids": [
+      "74402"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "gprs.claro.com.py",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "42702"
+    ],
+    "apns": [
+      {
+        "name": "Web",
+        "apn": "web.vodafone.com.qa",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Web (old)",
+        "apn": "vodafone.com.qa",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Q-Tel",
+    "ids": [
+      "42701"
+    ],
+    "apns": [
+      {
+        "name": "Qatarnet",
+        "apn": "gprs.qtel",
+        "type": [
+          "internet"
+        ],
+        "username": "gprs",
+        "password": "gprs"
+      },
+      {
+        "name": "Qtel MMS",
+        "apn": "mms.qtel",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsr.qtelmms.qa",
+        "mmsproxy": "10.23.8.3:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "SFR Réunion",
+    "ids": [
+      "64710"
+    ],
+    "apns": [
+      {
+        "name": "Contract / Prepaid",
+        "apn": "websfr",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "SFR slsfr",
+        "apn": "slsfr",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "SFR internetpro",
+        "apn": "internetpro",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "SFR ipnet",
+        "apn": "ipnet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMSGPRS",
+        "apn": "mmssfr",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms",
+        "mmsproxy": "10.0.224.145",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "22610"
+    ],
+    "apns": [
+      {
+        "name": "Orange Internet",
+        "apn": "net",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Orange MMS (MMS)",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://wap.mms.orange.ro:8002",
+        "mmsproxy": "62.217.247.252:8799",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "22601"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Internet (Prepaid)",
+        "apn": "tobe.vodafone.ro",
+        "type": [
+          "internet"
+        ],
+        "username": "tobe.vodafone.ro",
+        "password": "vodafone"
+      },
+      {
+        "name": "Mobile Internet (Postpaid)",
+        "apn": "internet.vodafone.ro",
+        "type": [
+          "internet"
+        ],
+        "username": "internet.vodafone.ro",
+        "password": "vodafone"
+      },
+      {
+        "name": "Mobile Internet (Prepaid)",
+        "apn": "internet.pre.vodafone.ro",
+        "type": [
+          "internet"
+        ],
+        "username": "internet.pre.vodafone.ro",
+        "password": "vodafone"
+      },
+      {
+        "name": "Live! (Postpaid)",
+        "apn": "live.vodafone.com",
+        "type": [
+          "internet"
+        ],
+        "username": "live",
+        "password": "vodafone"
+      },
+      {
+        "name": "Live! (Prepaid)",
+        "apn": "live.pre.vodafone.ro",
+        "type": [
+          "internet"
+        ],
+        "username": "live.pre.vodafone.com",
+        "password": "vodafone"
+      }
+    ]
+  },
+  {
+    "name": "Digi.Net Mobil",
+    "ids": [
+      "22605"
+    ],
+    "apns": [
+      {
+        "name": "Home",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Business (static)",
+        "apn": "static",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "22616"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.ro",
+        "type": [
+          "internet"
+        ],
+        "username": "lmro",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "Telenor",
+    "ids": [
+      "22001"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "telenor",
+        "password": "gprs"
+      },
+      {
+        "name": "Telenor MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.telenor.rs/servlets/mms",
+        "mmsproxy": "217.65.192.33:8080"
+      }
+    ]
+  },
+  {
+    "name": "Telekom Srbija",
+    "ids": [
+      "22003"
+    ],
+    "apns": [
+      {
+        "apn": "gprsinternet",
+        "type": [
+          "internet"
+        ],
+        "username": "mts",
+        "password": "064"
+      },
+      {
+        "name": "MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.mts064.telekom.yu/mms/wapenc",
+        "mmsproxy": "172.17.85.131:9201",
+        "username": "mts",
+        "password": "\"064\""
+      }
+    ]
+  },
+  {
+    "name": "VIP Mobile",
+    "ids": [
+      "22005"
+    ],
+    "apns": [
+      {
+        "apn": "vipmobile",
+        "type": [
+          "internet"
+        ],
+        "username": "vipmobile",
+        "password": "vipmobile"
+      },
+      {
+        "name": "Vip MMS",
+        "apn": "vipmobile.mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.vipmobile.rs",
+        "mmsproxy": "212.15.182.82:8080",
+        "username": "vipmobile",
+        "password": "vipmobile"
+      }
+    ]
+  },
+  {
+    "name": "MTN",
+    "ids": [
+      "63510"
+    ],
+    "apns": [
+      {
+        "apn": "internet.mtn",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Tigo",
+    "ids": [
+      "63513"
+    ],
+    "apns": [
+      {
+        "apn": "web.tigo.rw",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Beeline",
+    "ids": [
+      "25028",
+      "25099"
+    ],
+    "apns": [
+      {
+        "name": "3G modem",
+        "apn": "home.beeline.ru",
+        "type": [
+          "internet"
+        ],
+        "username": "beeline",
+        "password": "beeline"
+      },
+      {
+        "name": "Mobile phone",
+        "apn": "internet.beeline.ru",
+        "type": [
+          "internet"
+        ],
+        "username": "beeline",
+        "password": "beeline"
+      }
+    ]
+  },
+  {
+    "name": "MTS",
+    "ids": [
+      "25001"
+    ],
+    "apns": [
+      {
+        "name": "MTS internet",
+        "apn": "internet.mts.ru",
+        "type": [
+          "internet"
+        ],
+        "username": "mts",
+        "password": "mts"
+      }
+    ]
+  },
+  {
+    "name": "Gazprombank Mobile",
+    "ids": [
+      "25045"
+    ],
+    "apns": [
+      {
+        "apn": "gpb",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Letai",
+    "ids": [
+      "25027"
+    ],
+    "apns": [
+      {
+        "apn": "internet.letai.ru",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Megafon",
+    "ids": [
+      "25002"
+    ],
+    "apns": [
+      {
+        "name": "RUS",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "gdata",
+        "password": "gdata"
+      },
+      {
+        "name": "МегаФон MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc:8002",
+        "mmsproxy": "10.10.10.10:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "NTC",
+    "ids": [
+      "25016"
+    ],
+    "apns": [
+      {
+        "apn": "internet.ntc",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "mms.ntc",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.vntc.ru/was",
+        "mmsproxy": "80.243.64.68:8080"
+      }
+    ]
+  },
+  {
+    "name": "Motiv",
+    "ids": [
+      "25035"
+    ],
+    "apns": [
+      {
+        "name": "MOTIV",
+        "apn": "inet.ycc.ru",
+        "type": [
+          "internet"
+        ],
+        "username": "motiv",
+        "password": "motiv"
+      }
+    ]
+  },
+  {
+    "name": "Tele2",
+    "ids": [
+      "25020"
+    ],
+    "apns": [
+      {
+        "name": "TELE2 internet",
+        "apn": "internet.tele2.ru",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Phoenix",
+    "ids": [
+      "25097"
+    ],
+    "apns": [
+      {
+        "name": "Phoenix",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "SberMobile",
+    "ids": [
+      "25050"
+    ],
+    "apns": [
+      {
+        "name": "SberMobile Internet",
+        "apn": "internet.sberbank-tele.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "STS",
+    "ids": [
+      "25033"
+    ],
+    "apns": [
+      {
+        "apn": "internet.sts.ru",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Tinkoff Mobile",
+    "ids": [
+      "25062"
+    ],
+    "apns": [
+      {
+        "apn": "m.tinkoff",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Vainah Telecom",
+    "ids": [
+      "25008"
+    ],
+    "apns": [
+      {
+        "name": "vtk",
+        "apn": "vtk",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "VTB Mobile",
+    "ids": [
+      "25026"
+    ],
+    "apns": [
+      {
+        "name": "VTB",
+        "apn": "VTB",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Yota",
+    "ids": [
+      "25011"
+    ],
+    "apns": [
+      {
+        "name": "Internet for LTE modems",
+        "apn": "internet.yota",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Internet for LTE modems (in case internet.yota does not work)",
+        "apn": "yota.ru",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Mobily",
+    "ids": [
+      "42003"
+    ],
+    "apns": [
+      {
+        "name": "Postpaid",
+        "apn": "web1",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Prepaid",
+        "apn": "web2",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "mobily MMS (Postpaid)",
+        "apn": "mms1",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.3.3.133:9090/was",
+        "mmsproxy": "10.3.2.133:8080"
+      }
+    ]
+  },
+  {
+    "name": "STC",
+    "ids": [
+      "42001"
+    ],
+    "apns": [
+      {
+        "apn": "jawalnet.com.sa",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "mms.net.sa",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.net.sa:8002",
+        "mmsproxy": "10.1.1.1:8080"
+      },
+      {
+        "name": "ALJAWAL MMS",
+        "apn": "mms.net.sa",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.net.sa:8002",
+        "mmsproxy": "10.1.1.1:8080"
+      }
+    ]
+  },
+  {
+    "name": "Zain",
+    "ids": [
+      "42004"
+    ],
+    "apns": [
+      {
+        "apn": "zain",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "3",
+    "ids": [
+      "24002",
+      "24004"
+    ],
+    "apns": [
+      {
+        "name": "Mobiltelefon",
+        "apn": "data.tre.se",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Bredband",
+        "apn": "bredband.tre.se",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Bredband Kontantkort",
+        "apn": "net.tre.se",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Halebop",
+    "ids": [
+      "24001"
+    ],
+    "apns": [
+      {
+        "apn": "halebop.telia.se",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Halebop MMS",
+        "apn": "mms.telia.se",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmss/",
+        "mmsproxy": "193.209.134.132:80"
+      }
+    ]
+  },
+  {
+    "name": "Tele2",
+    "ids": [
+      "24005",
+      "24007"
+    ],
+    "apns": [
+      {
+        "name": "Mobilt Internet",
+        "apn": "internet.tele2.se",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Mobilt Bredband",
+        "apn": "mobileinternet.tele2.se",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Comviq",
+    "ids": [
+      "24005",
+      "24007"
+    ],
+    "apns": [
+      {
+        "name": "Surf",
+        "apn": "data.comviq.se",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Tele2 Comviq 3G",
+        "apn": "internet.tele2.se",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Tele2 Comviq 3G (7,2 Mbit/s)",
+        "apn": "mobileinternet.tele2.se",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Tele2 MMS",
+        "apn": "internet.tele2.se",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.tele2.se",
+        "mmsproxy": "130.244.202.30:8080"
+      }
+    ]
+  },
+  {
+    "name": "Multicom Security",
+    "ids": [
+      "24001",
+      "24005"
+    ],
+    "apns": [
+      {
+        "name": "Mobiflex",
+        "apn": "mobiflex.telia.se",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Telia MMS",
+        "apn": "mms.telia.se",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmss/",
+        "mmsproxy": "193.209.134.132:80"
+      }
+    ]
+  },
+  {
+    "name": "Telenor",
+    "ids": [
+      "24004",
+      "24006",
+      "24008"
+    ],
+    "apns": [
+      {
+        "name": "Mobilt Internet",
+        "apn": "internet.telenor.se",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Mobilsurf med maxtaxa",
+        "apn": "services.telenor.se",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Mobilt Bredband",
+        "apn": "bredband.telenor.se",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Cellmobile MMS",
+        "apn": "sp-services",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms",
+        "mmsproxy": "172.30.253.241:8799"
+      }
+    ]
+  },
+  {
+    "name": "Telia",
+    "ids": [
+      "24001",
+      "24005"
+    ],
+    "apns": [
+      {
+        "name": "Telia 3G",
+        "apn": "online.telia.se",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "TDC",
+    "ids": [
+      "24014"
+    ],
+    "apns": [
+      {
+        "apn": "internet.se",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "3mms",
+        "apn": "data.tre.se",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.tre.se",
+        "mmsproxy": "mmsproxy.tre.se:8799"
+      }
+    ]
+  },
+  {
+    "name": "djuice",
+    "ids": [
+      "24009"
+    ],
+    "apns": [
+      {
+        "apn": "internet.djuice.se",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Com Hem",
+    "ids": [
+      "24002",
+      "24004"
+    ],
+    "apns": [
+      {
+        "apn": "bredband.comhem.se",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "24012"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.se",
+        "type": [
+          "internet"
+        ],
+        "username": "lmse",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "M1",
+    "ids": [
+      "52503"
+    ],
+    "apns": [
+      {
+        "name": "SunSurf/Mobile Broadband (postpaid)",
+        "apn": "sunsurf",
+        "type": [
+          "internet"
+        ],
+        "username": "65"
+      },
+      {
+        "name": "MiWorld Mobile (postpaid)",
+        "apn": "miworld",
+        "type": [
+          "internet"
+        ],
+        "username": "65(mobilenumber)",
+        "password": "user123"
+      },
+      {
+        "name": "MiWorld Mobile (prepaid)",
+        "apn": "miworldcard",
+        "type": [
+          "internet"
+        ],
+        "username": "65(mobilenumber)",
+        "password": "user123"
+      },
+      {
+        "name": "Mobile Broadband (prepaid)",
+        "apn": "prepaidbb",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "M Card (prepaid)",
+        "apn": "sunsurfmcard",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "M1 MMS",
+        "apn": "miworld",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsgw:8002/",
+        "mmsproxy": "172.16.14.10:8080",
+        "username": "+65",
+        "password": "user123"
+      }
+    ]
+  },
+  {
+    "name": "SingTel",
+    "ids": [
+      "52501",
+      "52502"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "IDEAS MMS",
+        "apn": "e-ideas",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.singtel.com:10021/mmsc",
+        "mmsproxy": "165.21.42.84:8080",
+        "username": "65IDEAS",
+        "password": "IDEAS"
+      }
+    ]
+  },
+  {
+    "name": "Starhub",
+    "ids": [
+      "52505"
+    ],
+    "apns": [
+      {
+        "name": "WAP",
+        "apn": "shwap",
+        "type": [
+          "wap"
+        ],
+        "username": "star",
+        "password": "hub"
+      },
+      {
+        "name": "MaxMobile Broadband (prepaid)",
+        "apn": "shppd",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MaxMobile Broadband (postpaid)",
+        "apn": "shinternet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Gee! MMS",
+        "apn": "shmms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.starhubgee.com.sg:8002/",
+        "mmsproxy": "10.12.1.80:80"
+      }
+    ]
+  },
+  {
+    "name": "Mobitel",
+    "ids": [
+      "29341"
+    ],
+    "apns": [
+      {
+        "name": "Postpaid",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "mobitel",
+        "password": "internet"
+      },
+      {
+        "apn": "internetpro",
+        "type": [
+          "internet"
+        ],
+        "username": "mobitel",
+        "password": "internet"
+      }
+    ]
+  },
+  {
+    "name": "Vodafone / Simobil",
+    "ids": [
+      "29340"
+    ],
+    "apns": [
+      {
+        "apn": "internet.simobil.si",
+        "type": [
+          "internet"
+        ],
+        "username": "simobil",
+        "password": "internet"
+      },
+      {
+        "name": "SI mobil MMS",
+        "apn": "mms.simobil.si",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmc/",
+        "mmsproxy": "80.95.224.46:9201",
+        "username": "simobil",
+        "password": "internet"
+      }
+    ]
+  },
+  {
+    "name": "T-2",
+    "ids": [
+      "29364"
+    ],
+    "apns": [
+      {
+        "apn": "internet.t-2.net",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "T2 MMS",
+        "apn": "mms.t-2.net",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://www.mms.t-2.net:8002",
+        "mmsproxy": "172.20.18.137:8080"
+      }
+    ]
+  },
+  {
+    "name": "Telemach",
+    "ids": [
+      "29370"
+    ],
+    "apns": [
+      {
+        "name": "NET2GO/FREE2GO",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Slovak Telekom",
+    "ids": [
+      "23102",
+      "23104"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "T-Mobile MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms",
+        "mmsproxy": "192.168.1.1:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "23101"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "O2",
+    "ids": [
+      "23106"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "o2internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "O2 SK MMS",
+        "apn": "o2mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.o2world.sk:8002",
+        "mmsproxy": "10.97.1.11:8080"
+      }
+    ]
+  },
+  {
+    "name": "Tigo",
+    "ids": [
+      "60802"
+    ],
+    "apns": [
+      {
+        "apn": "wap.sentelgsm.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Movistar",
+    "ids": [
+      "70604"
+    ],
+    "apns": [
+      {
+        "apn": "internet.movistar.sv",
+        "type": [
+          "internet"
+        ],
+        "username": "movistarsv",
+        "password": "movistarsv"
+      }
+    ]
+  },
+  {
+    "name": "digicel",
+    "ids": [
+      "70602"
+    ],
+    "apns": [
+      {
+        "apn": "wap.digicelsv.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Digicel El Salvador MMS",
+        "apn": "wap.digicelsv.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://172.26.5.132/servlets/mms",
+        "mmsproxy": "172.26.5.12:8080"
+      }
+    ]
+  },
+  {
+    "name": "Tigo",
+    "ids": [
+      "70603"
+    ],
+    "apns": [
+      {
+        "apn": "internet.tigo.sv",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Claro",
+    "ids": [
+      "70601"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "internet.ideasclaro",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Zain",
+    "ids": [
+      "63401"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "MTN",
+    "ids": [
+      "63402"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Sudani",
+    "ids": [
+      "63407"
+    ],
+    "apns": [
+      {
+        "apn": "sudaninet",
+        "type": [
+          "internet"
+        ],
+        "username": "sudani",
+        "password": "sudani"
+      }
+    ]
+  },
+  {
+    "name": "AIS",
+    "ids": [
+      "52001"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "AIS-GPRS-3 MMS",
+        "apn": "multimedia",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.mobilelife.co.th",
+        "mmsproxy": "203.170.229.34:8080"
+      }
+    ]
+  },
+  {
+    "name": "AIS (AWN)",
+    "ids": [
+      "52003"
+    ],
+    "apns": [
+      {
+        "name": "AIS internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "authentication": "chap"
+      },
+      {
+        "name": "AIS MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.ais.co.th",
+        "mmsproxy": "203.170.229.34:8080",
+        "authentication": "chap"
+      }
+    ]
+  },
+  {
+    "name": "DTAC",
+    "ids": [
+      "52018"
+    ],
+    "apns": [
+      {
+        "apn": "www.dtac.co.th",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "DTAC-GPRS-3 MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.dtac.co.th:8002/",
+        "mmsproxy": "203.155.200.133:8080"
+      }
+    ]
+  },
+  {
+    "name": "True Move",
+    "ids": [
+      "52099"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "true",
+        "password": "true"
+      },
+      {
+        "name": "True GPRS 3 MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.trueworld.net:8002/",
+        "mmsproxy": "10.4.7.39:8080",
+        "username": "true",
+        "password": "true"
+      }
+    ]
+  },
+  {
+    "name": "TOT 3G",
+    "ids": [
+      "52015"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "60501"
+    ],
+    "apns": [
+      {
+        "name": "Internet",
+        "apn": "weborange",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Internet Everywhere Prepaid",
+        "apn": "keygp",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Internet Everywhere Professional",
+        "apn": "keypro",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Tunisie Télécom / TUNTEL",
+    "ids": [
+      "60502"
+    ],
+    "apns": [
+      {
+        "name": "GPRS DATA",
+        "apn": "gprs.tn",
+        "type": [
+          "internet"
+        ],
+        "username": "gprs",
+        "password": "gprs"
+      },
+      {
+        "name": "WEB DATA",
+        "apn": "internet.tn",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "mms.tn",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms",
+        "mmsproxy": "213.150.186.106:8080",
+        "username": "mms@tt1",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "60502"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.tn",
+        "type": [
+          "internet"
+        ],
+        "username": "lmtn",
+        "password": "plus"
+      }
+    ]
+  },
+  {
+    "name": "Tunisiana",
+    "ids": [
+      "60503"
+    ],
+    "apns": [
+      {
+        "name": "mms tunisiana",
+        "apn": "mms.tunisiana.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.tunisiana.com",
+        "mmsproxy": "10.3.2.100:80",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Avea",
+    "ids": [
+      "28603",
+      "28604"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "(former Aycell)",
+        "apn": "aycell",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Avea MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.avea.com.tr/servlets/mms",
+        "mmsproxy": "213.161.151.201:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Turkcell",
+    "ids": [
+      "28601"
+    ],
+    "apns": [
+      {
+        "name": "Turkcell internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Turkcell 3G",
+        "apn": "mgb",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Turkcell MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.turkcell.com.tr/servlets/mms",
+        "mmsproxy": "212.252.169.217:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Vodafone",
+    "ids": [
+      "28602"
+    ],
+    "apns": [
+      {
+        "name": "Vodafone Internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "vodafone",
+        "password": "vodafone"
+      },
+      {
+        "name": "KKTC Telsim",
+        "apn": "edge.kktctelsim.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Digicel",
+    "ids": [
+      "37413"
+    ],
+    "apns": [
+      {
+        "apn": "wap.digiceltt.com",
+        "type": [
+          "internet"
+        ],
+        "username": "wap",
+        "password": "wap"
+      },
+      {
+        "name": "Digicel Trinidad MMS",
+        "apn": "wap.digiceltt.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmc.digiceltt.com/servlets/mms",
+        "mmsproxy": "172.20.6.12:8080",
+        "username": "wap",
+        "password": "wap"
+      }
+    ]
+  },
+  {
+    "name": "bmobile / TSTT",
+    "ids": [
+      "37412"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "wap",
+        "password": "wap"
+      },
+      {
+        "name": "Bmobile mms",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://192.168.210.104/mmrelay.app",
+        "mmsproxy": "192.168.210.104:8080"
+      }
+    ]
+  },
+  {
+    "name": "Chunghwa Telecom (emome)",
+    "ids": [
+      "46692"
+    ],
+    "apns": [
+      {
+        "apn": "emome",
+        "type": [
+          "internet"
+        ],
+        "username": "web",
+        "password": "web"
+      },
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "CHT MMS",
+        "apn": "emome",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.emome.net:8002",
+        "mmsproxy": "10.1.1.1:8080"
+      }
+    ]
+  },
+  {
+    "name": "Far EasTone / KGT",
+    "ids": [
+      "46601"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "遠傳影音訊息",
+        "apn": "fetnet01",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms",
+        "mmsproxy": "210.241.199.199:9201"
+      }
+    ]
+  },
+  {
+    "name": "TW Mobile",
+    "ids": [
+      "46699"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "catch MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms",
+        "mmsproxy": "211.78.224.100:8080"
+      }
+    ]
+  },
+  {
+    "name": "TransAsia",
+    "ids": [
+      "46697"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "VIBO行動網-MMS",
+        "apn": "vibo",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms",
+        "mmsproxy": "172.24.128.36:8080"
+      }
+    ]
+  },
+  {
+    "name": "Vibo Telecom / Aurora",
+    "ids": [
+      "46689"
+    ],
+    "apns": [
+      {
+        "apn": "vibo",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Airtel Tanzania",
+    "ids": [
+      "64005"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Vodacom",
+    "ids": [
+      "64004"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Zantel",
+    "ids": [
+      "64003"
+    ],
+    "apns": [
+      {
+        "apn": "znet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "tiGO",
+    "ids": [
+      "64002"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "kyivstar",
+    "ids": [
+      "25503"
+    ],
+    "apns": [
+      {
+        "name": "Ace&Base",
+        "apn": "www.ab.kyivstar.net",
+        "type": [
+          "internet"
+        ],
+        "username": "igprs",
+        "password": "internet"
+      },
+      {
+        "name": "Contract GPRS",
+        "apn": "www.kyivstar.net",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Internet 3G",
+        "apn": "3g.kyivstar.net",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Kyivstar MMS",
+        "apn": "mms.kyivstar.net",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.kyivstar.net",
+        "mmsproxy": "10.10.10.10:8080",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Djuice",
+    "ids": [
+      "25503"
+    ],
+    "apns": [
+      {
+        "name": "Internet GPRS",
+        "apn": "www.djuice.com.ua",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Internet XL",
+        "apn": "xl.kyivstar.net",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Internet 3G",
+        "apn": "3g.kyivstar.net",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "life:)",
+    "ids": [
+      "25506"
+    ],
+    "apns": [
+      {
+        "name": "Standard",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Faster",
+        "apn": "speed",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Beeline",
+    "ids": [
+      "25502"
+    ],
+    "apns": [
+      {
+        "apn": "internet.beeline.ua",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Jeans",
+    "ids": [
+      "25501"
+    ],
+    "apns": [
+      {
+        "apn": "www.jeans.ua",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Hyper.NET",
+        "apn": "hyper.net",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "MTS",
+    "ids": [
+      "25501"
+    ],
+    "apns": [
+      {
+        "name": "GPRS Internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "internet"
+      },
+      {
+        "name": "Hyper.NET",
+        "apn": "hyper.net",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "HyperActive",
+        "apn": "active",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "umc.ua",
+        "apn": "www.umc.ua",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Utel",
+    "ids": [
+      "25507"
+    ],
+    "apns": [
+      {
+        "apn": "3g.utel.ua",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Utel MMS",
+        "apn": "3g.utel.ua",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.212.1.4/mms/wapenc",
+        "mmsproxy": "10.212.3.148:8080"
+      }
+    ]
+  },
+  {
+    "name": "MTN",
+    "ids": [
+      "64110"
+    ],
+    "apns": [
+      {
+        "apn": "yellopix.mtn.co.ug",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Orange",
+    "ids": [
+      "64114"
+    ],
+    "apns": [
+      {
+        "apn": "orange.ug",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "warid mms",
+        "apn": "mms.warid.co.ug",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.waridtel.co.ug"
+      }
+    ]
+  },
+  {
+    "name": "UTL",
+    "ids": [
+      "64111"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Broadband",
+        "apn": "utbroadband",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Mobile Internet",
+        "apn": "utweb",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Ug Telcom MMS",
+        "apn": "utwap",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.ugandatelecom.com/",
+        "mmsproxy": "10.76.101.51:8080"
+      }
+    ]
+  },
+  {
+    "name": "Warid",
+    "ids": [
+      "64122"
+    ],
+    "apns": [
+      {
+        "apn": "web.waridtel.co.ug",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Zain",
+    "ids": [
+      "64101"
+    ],
+    "apns": [
+      {
+        "apn": "web.ug.zain.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "+7Telecom",
+    "ids": [
+      "25096"
+    ],
+    "apns": [
+      {
+        "apn": "internet ",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      }
+    ]
+  },
+  {
+    "name": "Krymtelekom",
+    "ids": [
+      "25034"
+    ],
+    "apns": [
+      {
+        "name": "KTK",
+        "apn": "internet.ktkru.ru",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Volna mobile",
+    "ids": [
+      "25060"
+    ],
+    "apns": [
+      {
+        "name": "internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ],
+        "username": "internet",
+        "password": "internet"
+      }
+    ]
+  },
+  {
+    "name": "Win Mobile",
+    "ids": [
+      "25032"
+    ],
+    "apns": [
+      {
+        "name": "internet",
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "AT&T",
+    "ids": [
+      "310016",
+      "310038",
+      "310070",
+      "310080",
+      "310090",
+      "310090",
+      "310150",
+      "310280",
+      "310380",
+      "310410",
+      "310560",
+      "310670",
+      "310670",
+      "310680",
+      "310680",
+      "310950",
+      "311070",
+      "311090",
+      "311180",
+      "311190",
+      "312090"
+    ],
+    "apns": [
+      {
+        "name": "NXTGENPHONE",
+        "apn": "NXTGENPHONE",
+        "type": [
+          "internet",
+          "mms"
+        ],
+        "mmsc": "http://mmsc.mobile.att.net",
+        "mmsproxy": "proxy.mobile.att.net:80"
+      },
+      {
+        "name": "ENHANCEDPHONE",
+        "apn": "ENHANCEDPHONE",
+        "type": [
+          "internet",
+          "mms"
+        ],
+        "mmsc": "http://mmsc.mobile.att.net",
+        "mmsproxy": "proxy.mobile.att.net:80"
+      },
+      {
+        "name": "RESELLER",
+        "apn": "RESELLER",
+        "type": [
+          "internet",
+          "mms"
+        ],
+        "mmsc": "http://mmsc.mobile.att.net",
+        "mmsproxy": "proxy.mobile.att.net:80"
+      }
+    ]
+  },
+  {
+    "name": "T-Mobile",
+    "ids": [
+      "310026",
+      "310160",
+      "310200",
+      "310210",
+      "310220",
+      "310230",
+      "310240",
+      "310250",
+      "310260",
+      "310270",
+      "310310",
+      "310490",
+      "310580",
+      "310660",
+      "310800"
+    ],
+    "apns": [
+      {
+        "name": "T-Mobile LTE",
+        "apn": "fast.t-mobile.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Internet/WebConnect",
+        "apn": "epc.tmobile.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Web2Go/t-zones",
+        "apn": "wap.voicestream.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Internet (old)",
+        "apn": "internet2.voicestream.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Internet with VPN (old)",
+        "apn": "internet3.voicestream.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Broadband",
+        "apn": "mobilenet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Cincinnati Bell Wireless",
+    "ids": [
+      "310420"
+    ],
+    "apns": [
+      {
+        "apn": "wap.gocbw.com",
+        "type": [
+          "internet"
+        ],
+        "username": "cbw"
+      },
+      {
+        "name": "CBW MMS",
+        "apn": "wap.gocbw.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.gocbw.com:8088/mms",
+        "mmsproxy": "216.68.79.202:80",
+        "username": "cbw"
+      }
+    ]
+  },
+  {
+    "name": "Verizon",
+    "ids": [
+      "310010",
+      "310011",
+      "310012",
+      "311480",
+      "311480",
+      "311481",
+      "311482",
+      "311483",
+      "311484",
+      "311485",
+      "311486",
+      "311487",
+      "311488",
+      "311489"
+    ],
+    "apns": [
+      {
+        "name": "4G LTE Contract",
+        "apn": "vzwims",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "4G LTE Contract",
+        "apn": "vzwinternet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "4G LTE Contract",
+        "apn": "vzwapp",
+        "type": [
+          "wap"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Alltel",
+    "ids": [
+      "310590"
+    ],
+    "apns": [
+      {
+        "name": "Picture Message",
+        "apn": "MMS",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.mycellonephone.com/highland/mms.php",
+        "mmsproxy": "66.255.55.23:80"
+      },
+      {
+        "name": "CellularOne MMS",
+        "apn": "cellular1wap",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc",
+        "mmsproxy": "172.23.1.252:8799"
+      }
+    ]
+  },
+  {
+    "name": "Ting",
+    "ids": [
+      "310240"
+    ],
+    "apns": [
+      {
+        "name": "Ting Data",
+        "apn": "wireless.dish.com",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "wireless.dish.com",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://wholesale.mmsmvno.com/mms/wapenc"
+      },
+      {
+        "name": "Ting Data",
+        "apn": "tethering.dish.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "BendBroadband",
+    "ids": [
+      "311570"
+    ],
+    "apns": [
+      {
+        "apn": "ISP",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "MTPCS (Cellular One)",
+    "ids": [
+      "310570"
+    ],
+    "apns": [
+      {
+        "apn": "wapgw.chinookwireless.net",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "AweSIM",
+    "ids": [
+      "310410"
+    ],
+    "apns": [
+      {
+        "name": "AweSIM Internet",
+        "apn": "NXTGENPHONE",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "AweSIM MMS",
+        "apn": "NXTGENPHONE",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.mobile.att.net",
+        "mmsproxy": "proxy.mobile.att.net:80"
+      }
+    ]
+  },
+  {
+    "name": "Straight Talk",
+    "ids": [
+      "310410"
+    ],
+    "apns": [
+      {
+        "apn": "att.mvno",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "apn": "tfdata",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "SpeedTalk Mobile",
+    "ids": [
+      "310260"
+    ],
+    "apns": [
+      {
+        "name": "Cellular (MMS)",
+        "apn": "wholesale",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://wholesale.mmsmvno.com/mms/wapenc"
+      }
+    ]
+  },
+  {
+    "name": "Lycamobile",
+    "ids": [
+      "311960"
+    ],
+    "apns": [
+      {
+        "apn": "data.lycamobile.com",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Mint Mobile",
+    "ids": [
+      "310260"
+    ],
+    "apns": [
+      {
+        "name": "mint",
+        "apn": "wholesale",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "US Mobile",
+    "ids": [
+      "310260"
+    ],
+    "apns": [
+      {
+        "name": "US Mobile",
+        "apn": "pwg",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Ancel",
+    "ids": [
+      "74801"
+    ],
+    "apns": [
+      {
+        "name": "ADSL Móvil",
+        "apn": "adslmovil",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "ADSL Móvil Prepago",
+        "apn": "prepago.ancel",
+        "type": [
+          "internet"
+        ],
+        "username": "BAM",
+        "password": "BAM"
+      },
+      {
+        "name": "GPRS",
+        "apn": "gprs.ancel",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "mmsANCEL",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.mms.ancelutil.com.uy",
+        "mmsproxy": "200.40.246.2:3128"
+      }
+    ]
+  },
+  {
+    "name": "Claro",
+    "ids": [
+      "74810"
+    ],
+    "apns": [
+      {
+        "name": "3G Internet",
+        "apn": "gprs.claro.com.uy",
+        "type": [
+          "internet"
+        ],
+        "username": "ctigprs",
+        "password": "ctigprs999"
+      },
+      {
+        "name": "2G Internet",
+        "apn": "internet.ctimovil.com.uy",
+        "type": [
+          "internet"
+        ],
+        "username": "ctiweb",
+        "password": "ctiweb999"
+      }
+    ]
+  },
+  {
+    "name": "Movistar",
+    "ids": [
+      "74807"
+    ],
+    "apns": [
+      {
+        "name": "3G Internet",
+        "apn": "apnumt.movistar.com.uy",
+        "type": [
+          "internet"
+        ],
+        "username": "movistar",
+        "password": "movistar"
+      },
+      {
+        "name": "2G Internet",
+        "apn": "webapn.movistar.com.uy",
+        "type": [
+          "internet"
+        ],
+        "username": "movistar",
+        "password": "movistar"
+      }
+    ]
+  },
+  {
+    "name": "Beeline",
+    "ids": [
+      "43404"
+    ],
+    "apns": [
+      {
+        "apn": "internet.beeline.uz",
+        "type": [
+          "internet"
+        ],
+        "username": "beeline",
+        "password": "beeline"
+      }
+    ]
+  },
+  {
+    "name": "UMS",
+    "ids": [
+      "43407"
+    ],
+    "apns": [
+      {
+        "apn": "net.ums.uz",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Digicel",
+    "ids": [
+      "360070"
+    ],
+    "apns": [
+      {
+        "apn": "wap.digiceloecs.com",
+        "type": [
+          "internet"
+        ],
+        "username": "wapoecs",
+        "password": "wap03oecs"
+      }
+    ]
+  },
+  {
+    "name": "Digitel TIM",
+    "ids": [
+      "73401",
+      "73402",
+      "73403"
+    ],
+    "apns": [
+      {
+        "apn": "gprsweb.digitel.ve",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "expresate.digitel.ve",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.412.com.ve/servlets/mms",
+        "mmsproxy": "10.99.0.10:8080"
+      }
+    ]
+  },
+  {
+    "name": "Movilnet",
+    "ids": [
+      "73406"
+    ],
+    "apns": [
+      {
+        "apn": "int.movilnet.com.ve",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MMS",
+        "apn": "mm.movilnet.com.ve",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms2.movilnet.com.ve/servlets/mms",
+        "mmsproxy": "192.168.16.12:8080"
+      }
+    ]
+  },
+  {
+    "name": "Movistar",
+    "ids": [
+      "73404"
+    ],
+    "apns": [
+      {
+        "apn": "internet.movistar.ve",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "MobiFone",
+    "ids": [
+      "45201"
+    ],
+    "apns": [
+      {
+        "apn": "m-wap",
+        "type": [
+          "internet"
+        ],
+        "username": "mms",
+        "password": "mms"
+      },
+      {
+        "name": "Mobifone MMS",
+        "apn": "m-i090",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://203.162.21.114/mmsc",
+        "mmsproxy": "203.162.21.114:3130",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Vinaphone",
+    "ids": [
+      "45202"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Internet",
+        "apn": "m3-world",
+        "type": [
+          "internet"
+        ],
+        "username": "mms",
+        "password": "mms"
+      },
+      {
+        "name": "Mobile Broadband",
+        "apn": "m3-card",
+        "type": [
+          "internet"
+        ],
+        "username": "mms",
+        "password": "mms"
+      },
+      {
+        "name": "Vinaphone MMS",
+        "apn": "m3-mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.vinaphone.com.vn",
+        "mmsproxy": "10.1.10.46:8000",
+        "username": "mms",
+        "password": "mms"
+      }
+    ]
+  },
+  {
+    "name": "Viettel Mobile",
+    "ids": [
+      "45204"
+    ],
+    "apns": [
+      {
+        "name": "Mobile Internet",
+        "apn": "v-internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "D-com 3G",
+        "apn": "e-connect",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Viettel MMS",
+        "apn": "v-mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.viettelmobile.com.vn/mms/wapenc",
+        "mmsproxy": "192.168.233.10:8080"
+      }
+    ]
+  },
+  {
+    "name": "Vietnamobile",
+    "ids": [
+      "45205"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Vietnamobile MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://10.10.128.58/servlets/mms",
+        "mmsproxy": "10.10.128.44:8080"
+      }
+    ]
+  },
+  {
+    "name": "EVNTelecom/E-Mobile",
+    "ids": [
+      "45208"
+    ],
+    "apns": [
+      {
+        "name": "EVNTelecomNet",
+        "apn": "e-internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Beeline VN",
+    "ids": [
+      "45207"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Cell-c",
+    "ids": [
+      "65507"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Cell-C MMS",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.cmobile.co.za/",
+        "mmsproxy": "196.31.116.250"
+      }
+    ]
+  },
+  {
+    "name": "MTN",
+    "ids": [
+      "65510"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "MTN MMS",
+        "apn": "mymtn",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.mtn.co.za/mms/wapenc",
+        "mmsproxy": "196.11.240.211:8080",
+        "username": "mtnmms",
+        "password": "mtnmms"
+      }
+    ]
+  },
+  {
+    "name": "Vodacom",
+    "ids": [
+      "65501"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Unrestricted",
+        "apn": "unrestricted",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "Vlive!MMS",
+        "apn": "mms.vodacom.net",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mmsc.vodacom4me.co.za",
+        "mmsproxy": "196.6.128.13:8080"
+      }
+    ]
+  },
+  {
+    "name": "Virgin Mobile",
+    "ids": [
+      "65507"
+    ],
+    "apns": [
+      {
+        "apn": "vdata",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "8.ta",
+    "ids": [
+      "65502"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      },
+      {
+        "name": "8 ta mms",
+        "apn": "mms",
+        "type": [
+          "mms"
+        ],
+        "mmsc": "http://mms.8ta.com:38090/was",
+        "mmsproxy": "10.148.29.101:8080"
+      }
+    ]
+  },
+  {
+    "name": "MTN Eswatini",
+    "ids": [
+      "65310"
+    ],
+    "apns": [
+      {
+        "apn": "mymtn.co.sz",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "Eswatini Mobile",
+    "ids": [
+      "65302"
+    ],
+    "apns": [
+      {
+        "apn": "internet",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  },
+  {
+    "name": "IPKO",
+    "ids": [
+      "22102"
+    ],
+    "apns": [
+      {
+        "name": "ipko",
+        "apn": "ipko",
+        "type": [
+          "internet"
+        ]
+      }
+    ]
+  }
+]
\ No newline at end of file
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 09/15] provision: Add new module
  2023-12-19 18:36 [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
                   ` (6 preceding siblings ...)
  2023-12-19 18:37 ` [PATCH v2 08/15] provision: Import initial JSON db Denis Kenzior
@ 2023-12-19 18:37 ` Denis Kenzior
  2023-12-19 18:37 ` [PATCH v2 10/15] gprs: Use the new provisioning module Denis Kenzior
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2023-12-19 18:37 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

This module will replace the gprs-provision module.  The new provisiondb
supercedes all other plugins in capability and there's no desire to
maintain the old code any longer.
---
 Makefile.am     |  3 +-
 src/ofono.h     |  5 ++++
 src/provision.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+), 1 deletion(-)
 create mode 100644 src/provision.c

diff --git a/Makefile.am b/Makefile.am
index 3023ed0c..cfa05bf7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -726,7 +726,8 @@ src_ofonod_SOURCES = $(builtin_sources) $(gatchat_sources) src/ofono.ver \
 			src/netmon.c src/lte.c src/ims.c \
 			src/netmonagent.c src/netmonagent.h \
 			src/module.c \
-			src/provisiondb.h src/provisiondb.c
+			src/provisiondb.h src/provisiondb.c \
+			src/provision.c
 
 src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) $(ell_ldadd) \
 			@GLIB_LIBS@ @DBUS_LIBS@ -ldl
diff --git a/src/ofono.h b/src/ofono.h
index e289ff08..6a8c53a1 100644
--- a/src/ofono.h
+++ b/src/ofono.h
@@ -582,6 +582,11 @@ void __ofono_nettime_info_received(struct ofono_modem *modem,
 #include <ofono/sim-auth.h>
 
 #include <ofono/gprs-provision.h>
+bool __ofono_provision_get_settings(const char *mcc,
+				const char *mnc, const char *spn,
+				struct ofono_gprs_provision_data **settings,
+				size_t *count);
+
 ofono_bool_t __ofono_gprs_provision_get_settings(const char *mcc,
 				const char *mnc, const char *spn,
 				struct ofono_gprs_provision_data **settings,
diff --git a/src/provision.c b/src/provision.c
new file mode 100644
index 00000000..e419d15c
--- /dev/null
+++ b/src/provision.c
@@ -0,0 +1,73 @@
+/*
+ *  oFono - Open Source Telephony
+ *  Copyright (C) 2023  Cruise, LLC
+ *
+ *  SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stddef.h>
+
+#include "provisiondb.h"
+#include "ofono.h"
+
+static struct provision_db *pdb;
+
+bool __ofono_provision_get_settings(const char *mcc,
+				const char *mnc, const char *spn,
+				struct ofono_gprs_provision_data **settings,
+				size_t *count)
+{
+	size_t n_contexts;
+	struct ofono_gprs_provision_data *contexts;
+	int r;
+	size_t i;
+
+	if (mcc == NULL || strlen(mcc) == 0 || mnc == NULL || strlen(mnc) == 0)
+		return false;
+
+	r = provision_db_lookup(pdb, mcc, mnc, spn, &contexts, &n_contexts);
+	if (r < 0)
+		return false;
+
+	DBG("Obtained %zd contexts for %s%s, spn: %s",
+			n_contexts, mcc, mnc, spn);
+
+	for (i = 0; i < n_contexts; i++) {
+		struct ofono_gprs_provision_data *ap = contexts + i;
+
+		DBG("APN: %s, Type: %x, Proto: %x",
+				ap->apn, ap->type, ap->proto);
+
+		if (ap->type & OFONO_GPRS_CONTEXT_TYPE_MMS)
+			DBG("MMS Proxy: %s, MMSC: %s", ap->message_proxy,
+					ap->message_center);
+	}
+
+	*count = n_contexts;
+	*settings = contexts;
+
+	return true;
+}
+
+static int provision_init(void)
+{
+	DBG("");
+
+	pdb = provision_db_new_default();
+
+	if (!pdb)
+		l_warn("Unable to open provisioning database!");
+
+	return 0;
+}
+
+static void provision_exit(void)
+{
+	provision_db_free(pdb);
+}
+
+OFONO_MODULE(provision, provision_init, provision_exit)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 10/15] gprs: Use the new provisioning module
  2023-12-19 18:36 [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
                   ` (7 preceding siblings ...)
  2023-12-19 18:37 ` [PATCH v2 09/15] provision: Add new module Denis Kenzior
@ 2023-12-19 18:37 ` Denis Kenzior
  2023-12-19 18:37 ` [PATCH v2 11/15] plugins: Remove support for file-provision plugin Denis Kenzior
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2023-12-19 18:37 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

---
 src/gprs.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/src/gprs.c b/src/gprs.c
index 27aeb68c..40642324 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -2376,6 +2376,7 @@ static void provision_context(const struct ofono_gprs_provision_data *ap,
 {
 	unsigned int id;
 	struct pri_context *context = NULL;
+	enum ofono_gprs_context_type type;
 
 	/* Sanity check */
 	if (ap == NULL)
@@ -2408,10 +2409,19 @@ static void provision_context(const struct ofono_gprs_provision_data *ap,
 							gprs->last_context_id);
 	else
 		id = l_uintset_find_unused_min(gprs->used_pids);
+
 	if (id > l_uintset_get_max(gprs->used_pids))
 		return;
 
-	context = pri_context_create(gprs, ap->name, ap->type);
+	/*
+	 * Right now oFono is not setup to handle contexts with multiple
+	 * types due to the way the D-Bus API is structured.  This mainly
+	 * affects Internet + MMS contexts.  For now, work around this
+	 * by selecting the primary (lowest bit) context type
+	 */
+	type = 1 << (__builtin_ffs(ap->type) - 1);
+
+	context = pri_context_create(gprs, ap->name, type);
 	if (context == NULL)
 		return;
 
@@ -2429,7 +2439,7 @@ static void provision_context(const struct ofono_gprs_provision_data *ap,
 	strcpy(context->context.apn, ap->apn);
 	context->context.proto = ap->proto;
 
-	if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
+	if (type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
 		if (ap->message_proxy != NULL)
 			strcpy(context->message_proxy, ap->message_proxy);
 
@@ -2454,11 +2464,10 @@ static void provision_contexts(struct ofono_gprs *gprs, const char *mcc,
 				const char *mnc, const char *spn)
 {
 	struct ofono_gprs_provision_data *settings;
-	int count;
-	int i;
+	size_t count;
+	size_t i;
 
-	if (__ofono_gprs_provision_get_settings(mcc, mnc, spn,
-						&settings, &count) == FALSE) {
+	if (!__ofono_provision_get_settings(mcc, mnc, spn, &settings, &count)) {
 		ofono_warn("Provisioning failed");
 		return;
 	}
@@ -2466,7 +2475,7 @@ static void provision_contexts(struct ofono_gprs *gprs, const char *mcc,
 	for (i = 0; i < count; i++)
 		provision_context(&settings[i], gprs);
 
-	__ofono_gprs_provision_free_settings(settings, count);
+	l_free(settings);
 }
 
 static void remove_non_active_context(struct ofono_gprs *gprs,
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 11/15] plugins: Remove support for file-provision plugin
  2023-12-19 18:36 [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
                   ` (8 preceding siblings ...)
  2023-12-19 18:37 ` [PATCH v2 10/15] gprs: Use the new provisioning module Denis Kenzior
@ 2023-12-19 18:37 ` Denis Kenzior
  2023-12-19 18:37 ` [PATCH v2 12/15] plugins: provision: Remove mbpi support Denis Kenzior
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2023-12-19 18:37 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

---
 Makefile.am              |   3 -
 plugins/file-provision.c | 172 ---------------------------------------
 2 files changed, 175 deletions(-)
 delete mode 100644 plugins/file-provision.c

diff --git a/Makefile.am b/Makefile.am
index cfa05bf7..a7404121 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -658,9 +658,6 @@ builtin_sources += plugins/mbpi.h plugins/mbpi.c
 
 builtin_modules += provision
 builtin_sources += plugins/provision.c
-
-builtin_modules += file_provision
-builtin_sources += plugins/file-provision.c
 endif
 
 if MAINTAINER_MODE
diff --git a/plugins/file-provision.c b/plugins/file-provision.c
deleted file mode 100644
index a3829a34..00000000
--- a/plugins/file-provision.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- *
- *  oFono - Open Source Telephony
- *
- *  Copyright (C) 2017  Kerlink SA.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- *  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.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <glib.h>
-
-#define OFONO_API_SUBJECT_TO_CHANGE
-#include <ofono/modem.h>
-#include <ofono/gprs-provision.h>
-#include <ofono/log.h>
-#include <ofono/plugin.h>
-
-#define CONFIG_FILE STORAGEDIR "/provisioning"
-
-static int config_file_provision_get_settings(const char *mcc,
-				const char *mnc, const char *spn,
-				struct ofono_gprs_provision_data **settings,
-				int *count)
-{
-	int result = 0;
-	GKeyFile *key_file = NULL;
-	char *setting_group = NULL;
-	char *value;
-
-	DBG("Finding settings for MCC %s, MNC %s, SPN '%s'", mcc, mnc, spn);
-
-	*count = 0;
-	*settings = NULL;
-
-	key_file = g_key_file_new();
-
-	if (!g_key_file_load_from_file(key_file, CONFIG_FILE, 0, NULL)) {
-		result = -ENOENT;
-		goto error;
-	}
-
-	setting_group = g_try_malloc(strlen("operator:") + strlen(mcc) +
-							strlen(mnc) + 2);
-	if (setting_group == NULL) {
-		result = -ENOMEM;
-		goto error;
-	}
-
-	sprintf(setting_group, "operator:%s,%s", mcc, mnc);
-
-	value = g_key_file_get_string(key_file, setting_group,
-					"internet.AccessPointName", NULL);
-
-	if (value == NULL)
-		goto error;
-
-	*settings = g_try_new0(struct ofono_gprs_provision_data, 1);
-	if (*settings == NULL) {
-		result = -ENOMEM;
-		goto error;
-	}
-
-	*count = 1;
-
-	(*settings)[0].type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
-	(*settings)[0].apn = value;
-
-	value = g_key_file_get_string(key_file, setting_group,
-					"internet.Username", NULL);
-
-	if (value != NULL)
-		(*settings)[0].username = value;
-
-	value = g_key_file_get_string(key_file, setting_group,
-					"internet.Password", NULL);
-
-	if (value != NULL)
-		(*settings)[0].password = value;
-
-	/* select default authentication method */
-	(*settings)[0].auth_method = OFONO_GPRS_AUTH_METHOD_CHAP;
-
-	value = g_key_file_get_string(key_file, setting_group,
-					"internet.AuthenticationMethod", NULL);
-
-	if (value != NULL) {
-		if (g_strcmp0(value, "chap") == 0)
-			(*settings)[0].auth_method =
-						OFONO_GPRS_AUTH_METHOD_CHAP;
-		else if (g_strcmp0(value, "pap") == 0)
-			(*settings)[0].auth_method =
-						OFONO_GPRS_AUTH_METHOD_PAP;
-		else if (g_strcmp0(value, "none") != 0)
-			DBG("Unknown auth method: %s", value);
-
-		g_free(value);
-	}
-
-	(*settings)[0].proto = OFONO_GPRS_PROTO_IP;
-	value = g_key_file_get_string(key_file, setting_group,
-					"internet.Protocol", NULL);
-
-	if (value != NULL) {
-		DBG("CRO value:%s", value);
-		if (g_strcmp0(value, "ip") == 0) {
-			DBG("CRO value=ip");
-			(*settings)[0].proto = OFONO_GPRS_PROTO_IP;
-		} else if (g_strcmp0(value, "ipv6") == 0) {
-			DBG("CRO value=ipv6");
-			(*settings)[0].proto = OFONO_GPRS_PROTO_IPV6;
-		} else if (g_strcmp0(value, "dual") == 0)
-			(*settings)[0].proto = OFONO_GPRS_PROTO_IPV4V6;
-		else
-			DBG("Unknown protocol: %s", value);
-
-		g_free(value);
-	}
-
-error:
-	if (key_file != NULL)
-		g_key_file_free(key_file);
-
-	if (setting_group != NULL)
-		g_free(setting_group);
-
-	if (result == 0 && *count > 0)
-		DBG("Found. APN:%s, proto:%d, auth_method:%d",
-				(*settings)[0].apn, (*settings)[0].proto,
-				(*settings)[0].auth_method);
-	else
-		DBG("Not found. Result:%d", result);
-
-	return result;
-}
-
-static struct ofono_gprs_provision_driver config_file_provision_driver = {
-	.name		= "GPRS context provisioning",
-	.get_settings	= config_file_provision_get_settings,
-};
-
-static int config_file_provision_init(void)
-{
-	return ofono_gprs_provision_driver_register(
-						&config_file_provision_driver);
-}
-
-static void config_file_provision_exit(void)
-{
-	ofono_gprs_provision_driver_unregister(
-						&config_file_provision_driver);
-}
-
-OFONO_PLUGIN_DEFINE(file_provision, "Gprs Provisioning Plugin",
-			VERSION, OFONO_PLUGIN_PRIORITY_HIGH,
-			config_file_provision_init,
-			config_file_provision_exit)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 12/15] plugins: provision: Remove mbpi support
  2023-12-19 18:36 [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
                   ` (9 preceding siblings ...)
  2023-12-19 18:37 ` [PATCH v2 11/15] plugins: Remove support for file-provision plugin Denis Kenzior
@ 2023-12-19 18:37 ` Denis Kenzior
  2023-12-19 18:37 ` [PATCH v2 13/15] examples: Remove provision example Denis Kenzior
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2023-12-19 18:37 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

This is now completely superceded by the provisiondb infrastructure.
---
 Makefile.am         |   7 -
 configure.ac        |  24 ---
 plugins/mbpi.c      | 506 --------------------------------------------
 plugins/mbpi.h      |  27 ---
 plugins/provision.c | 118 -----------
 5 files changed, 682 deletions(-)
 delete mode 100644 plugins/mbpi.c
 delete mode 100644 plugins/mbpi.h
 delete mode 100644 plugins/provision.c

diff --git a/Makefile.am b/Makefile.am
index a7404121..447f2466 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -653,13 +653,6 @@ builtin_sources += plugins/upower.c
 endif
 endif
 
-if PROVISION
-builtin_sources += plugins/mbpi.h plugins/mbpi.c
-
-builtin_modules += provision
-builtin_sources += plugins/provision.c
-endif
-
 if MAINTAINER_MODE
 builtin_modules += example_history
 builtin_sources += examples/history.c
diff --git a/configure.ac b/configure.ac
index 626055ad..d48235b6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -239,30 +239,6 @@ fi
 AM_CONDITIONAL(BLUEZ4, test "${enable_bluetooth}" != "no" && test "${enable_bluez4}" = "yes")
 AM_CONDITIONAL(BLUETOOTH, test "${enable_bluetooth}" != "no")
 
-AC_ARG_WITH([provisiondb], AS_HELP_STRING([--with-provisiondb=FILE],
-	[location of provision database]), [path_provisiondb=${withval}])
-
-AC_ARG_ENABLE(provision, AS_HELP_STRING([--disable-provision],
-				[disable provisioning support]),
-					[enable_provision=${enableval}])
-if (test "${enable_provision}" != "no"); then
-	if (test -n "${path_provisiondb}"); then
-		AC_DEFINE_UNQUOTED(PROVIDER_DATABASE, "${path_provisiondb}",
-						[Mobile provider database])
-	else
-		AC_MSG_CHECKING([for mobile-broadband-provider-info])
-		PKG_CHECK_EXISTS(mobile-broadband-provider-info,
-			_PKG_CONFIG(PROVIDER_DATABASE, [variable=database],
-					[mobile-broadband-provider-info])
-			AC_DEFINE_UNQUOTED(PROVIDER_DATABASE,
-						"$pkg_cv_PROVIDER_DATABASE",
-						[Mobile provider database])
-			AC_MSG_RESULT([yes]),
-			AC_MSG_ERROR(Mobile broadband provider database is required))
-	fi
-fi
-AM_CONDITIONAL(PROVISION, test "${enable_provision}" != "no")
-
 AC_ARG_ENABLE(upower, AS_HELP_STRING([--disable-upower],
 			[disable UPower plugin]),
 					[enable_upower=${enableval}])
diff --git a/plugins/mbpi.c b/plugins/mbpi.c
deleted file mode 100644
index d91f8e07..00000000
--- a/plugins/mbpi.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- *
- *  oFono - Open Source Telephony
- *
- *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- *  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 General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include <glib.h>
-
-#define OFONO_API_SUBJECT_TO_CHANGE
-#include <ofono/modem.h>
-#include <ofono/gprs-provision.h>
-
-#ifndef MBPI_DATABASE
-#define MBPI_DATABASE  "/usr/share/mobile-broadband-provider-info/" \
-							"serviceproviders.xml"
-#endif
-
-#include "mbpi.h"
-
-#define _(x) case x: return (#x)
-
-enum MBPI_ERROR {
-	MBPI_ERROR_DUPLICATE,
-};
-
-struct gsm_data {
-	const char *match_mcc;
-	const char *match_mnc;
-	GSList *apns;
-	gboolean match_found;
-	gboolean allow_duplicates;
-};
-
-const char *mbpi_ap_type(enum ofono_gprs_context_type type)
-{
-	switch (type) {
-		_(OFONO_GPRS_CONTEXT_TYPE_ANY);
-		_(OFONO_GPRS_CONTEXT_TYPE_INTERNET);
-		_(OFONO_GPRS_CONTEXT_TYPE_MMS);
-		_(OFONO_GPRS_CONTEXT_TYPE_WAP);
-		_(OFONO_GPRS_CONTEXT_TYPE_IMS);
-	}
-
-	return "OFONO_GPRS_CONTEXT_TYPE_<UNKNOWN>";
-}
-
-static GQuark mbpi_error_quark(void)
-{
-	return g_quark_from_static_string("ofono-mbpi-error-quark");
-}
-
-void mbpi_ap_free(struct ofono_gprs_provision_data *ap)
-{
-	g_free(ap->name);
-	g_free(ap->apn);
-	g_free(ap->username);
-	g_free(ap->password);
-	g_free(ap->message_proxy);
-	g_free(ap->message_center);
-
-	g_free(ap);
-}
-
-static void mbpi_g_set_error(GMarkupParseContext *context, GError **error,
-				GQuark domain, gint code, const gchar *fmt, ...)
-{
-	va_list ap;
-	gint line_number, char_number;
-
-	g_markup_parse_context_get_position(context, &line_number,
-						&char_number);
-	va_start(ap, fmt);
-
-	*error = g_error_new_valist(domain, code, fmt, ap);
-
-	va_end(ap);
-
-	g_prefix_error(error, "%s:%d ", MBPI_DATABASE, line_number);
-}
-
-static void text_handler(GMarkupParseContext *context,
-				const gchar *text, gsize text_len,
-				gpointer userdata, GError **error)
-{
-	char **string = userdata;
-
-	*string = g_strndup(text, text_len);
-}
-
-static const GMarkupParser text_parser = {
-	NULL,
-	NULL,
-	text_handler,
-	NULL,
-	NULL,
-};
-
-static void authentication_start(GMarkupParseContext *context,
-			const gchar **attribute_names,
-			const gchar **attribute_values,
-			enum ofono_gprs_auth_method *auth_method,
-			GError **error)
-{
-	const char *text = NULL;
-	int i;
-
-	for (i = 0; attribute_names[i]; i++)
-		if (g_str_equal(attribute_names[i], "method") == TRUE)
-			text = attribute_values[i];
-
-	if (text == NULL) {
-		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
-					G_MARKUP_ERROR_MISSING_ATTRIBUTE,
-					"Missing attribute: method");
-		return;
-	}
-
-	if (strcmp(text, "chap") == 0)
-		*auth_method = OFONO_GPRS_AUTH_METHOD_CHAP;
-	else if (strcmp(text, "pap") == 0)
-		*auth_method = OFONO_GPRS_AUTH_METHOD_PAP;
-	else
-		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
-					G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
-					"Unknown authentication method: %s",
-					text);
-}
-
-static void usage_start(GMarkupParseContext *context,
-			const gchar **attribute_names,
-			const gchar **attribute_values,
-			enum ofono_gprs_context_type *type, GError **error)
-{
-	const char *text = NULL;
-	int i;
-
-	for (i = 0; attribute_names[i]; i++)
-		if (g_str_equal(attribute_names[i], "type") == TRUE)
-			text = attribute_values[i];
-
-	if (text == NULL) {
-		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
-					G_MARKUP_ERROR_MISSING_ATTRIBUTE,
-					"Missing attribute: type");
-		return;
-	}
-
-	if (strcmp(text, "internet") == 0)
-		*type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
-	else if (strcmp(text, "mms") == 0)
-		*type = OFONO_GPRS_CONTEXT_TYPE_MMS;
-	else if (strcmp(text, "wap") == 0)
-		*type = OFONO_GPRS_CONTEXT_TYPE_WAP;
-	else if (strcmp(text, "mms-internet-hipri-fota") == 0)
-		*type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
-	else if (strcmp(text, "mms-internet-hipri") == 0)
-		*type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
-	else
-		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
-					G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
-					"Unknown usage attribute: %s", text);
-}
-
-static void apn_start(GMarkupParseContext *context, const gchar *element_name,
-			const gchar **attribute_names,
-			const gchar **attribute_values,
-			gpointer userdata, GError **error)
-{
-	struct ofono_gprs_provision_data *apn = userdata;
-
-	if (g_str_equal(element_name, "name"))
-		g_markup_parse_context_push(context, &text_parser, &apn->name);
-	else if (g_str_equal(element_name, "username"))
-		g_markup_parse_context_push(context, &text_parser,
-						&apn->username);
-	else if (g_str_equal(element_name, "password"))
-		g_markup_parse_context_push(context, &text_parser,
-						&apn->password);
-	else if (g_str_equal(element_name, "authentication"))
-		authentication_start(context, attribute_names,
-				attribute_values, &apn->auth_method, error);
-	else if (g_str_equal(element_name, "mmsc"))
-		g_markup_parse_context_push(context, &text_parser,
-						&apn->message_center);
-	else if (g_str_equal(element_name, "mmsproxy"))
-		g_markup_parse_context_push(context, &text_parser,
-						&apn->message_proxy);
-	else if (g_str_equal(element_name, "usage"))
-		usage_start(context, attribute_names, attribute_values,
-				&apn->type, error);
-}
-
-static void apn_end(GMarkupParseContext *context, const gchar *element_name,
-			gpointer userdata, GError **error)
-{
-	if (g_str_equal(element_name, "name") ||
-			g_str_equal(element_name, "username") ||
-			g_str_equal(element_name, "password") ||
-			g_str_equal(element_name, "mmsc") ||
-			g_str_equal(element_name, "mmsproxy"))
-		g_markup_parse_context_pop(context);
-}
-
-static void apn_error(GMarkupParseContext *context, GError *error,
-			gpointer userdata)
-{
-	/*
-	 * Note that even if the error happened in a subparser, this will
-	 * be called.  So we always perform cleanup of the allocated
-	 * provision data
-	 */
-	mbpi_ap_free(userdata);
-}
-
-static const GMarkupParser apn_parser = {
-	apn_start,
-	apn_end,
-	NULL,
-	NULL,
-	apn_error,
-};
-
-static const GMarkupParser skip_parser = {
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-};
-
-static void network_id_handler(GMarkupParseContext *context,
-				struct gsm_data *gsm,
-				const gchar **attribute_names,
-				const gchar **attribute_values,
-				GError **error)
-{
-	const char *mcc = NULL, *mnc = NULL;
-	int i;
-
-	for (i = 0; attribute_names[i]; i++) {
-		if (g_str_equal(attribute_names[i], "mcc") == TRUE)
-			mcc = attribute_values[i];
-		if (g_str_equal(attribute_names[i], "mnc") == TRUE)
-			mnc = attribute_values[i];
-	}
-
-	if (mcc == NULL) {
-		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
-					G_MARKUP_ERROR_MISSING_ATTRIBUTE,
-					"Missing attribute: mcc");
-		return;
-	}
-
-	if (mnc == NULL) {
-		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
-					G_MARKUP_ERROR_MISSING_ATTRIBUTE,
-					"Missing attribute: mnc");
-		return;
-	}
-
-	if (g_str_equal(mcc, gsm->match_mcc) &&
-			g_str_equal(mnc, gsm->match_mnc))
-		gsm->match_found = TRUE;
-}
-
-static void apn_handler(GMarkupParseContext *context, struct gsm_data *gsm,
-			const gchar **attribute_names,
-			const gchar **attribute_values,
-			GError **error)
-{
-	struct ofono_gprs_provision_data *ap;
-	const char *apn;
-	int i;
-
-	if (gsm->match_found == FALSE) {
-		g_markup_parse_context_push(context, &skip_parser, NULL);
-		return;
-	}
-
-	for (i = 0, apn = NULL; attribute_names[i]; i++) {
-		if (g_str_equal(attribute_names[i], "value") == FALSE)
-			continue;
-
-		apn = attribute_values[i];
-		break;
-	}
-
-	if (apn == NULL) {
-		mbpi_g_set_error(context, error, G_MARKUP_ERROR,
-					G_MARKUP_ERROR_MISSING_ATTRIBUTE,
-					"APN attribute missing");
-		return;
-	}
-
-	ap = g_new0(struct ofono_gprs_provision_data, 1);
-	ap->apn = g_strdup(apn);
-	ap->type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
-	ap->proto = OFONO_GPRS_PROTO_IP;
-	ap->auth_method = OFONO_GPRS_AUTH_METHOD_CHAP;
-
-	g_markup_parse_context_push(context, &apn_parser, ap);
-}
-
-static void gsm_start(GMarkupParseContext *context, const gchar *element_name,
-			const gchar **attribute_names,
-			const gchar **attribute_values,
-			gpointer userdata, GError **error)
-{
-	if (g_str_equal(element_name, "network-id")) {
-		struct gsm_data *gsm = userdata;
-
-		/*
-		 * For entries with multiple network-id elements, don't bother
-		 * searching if we already have a match
-		 */
-		if (gsm->match_found == TRUE)
-			return;
-
-		network_id_handler(context, userdata, attribute_names,
-					attribute_values, error);
-	} else if (g_str_equal(element_name, "apn"))
-		apn_handler(context, userdata, attribute_names,
-				attribute_values, error);
-}
-
-static void gsm_end(GMarkupParseContext *context, const gchar *element_name,
-			gpointer userdata, GError **error)
-{
-	struct gsm_data *gsm;
-	struct ofono_gprs_provision_data *ap;
-
-	if (!g_str_equal(element_name, "apn"))
-		return;
-
-	gsm = userdata;
-
-	ap = g_markup_parse_context_pop(context);
-	if (ap == NULL)
-		return;
-
-	/* select authentication method NONE if others cannot be used */
-	if (!ap->username || (!ap->username && !ap->password))
-		ap->auth_method = OFONO_GPRS_AUTH_METHOD_NONE;
-
-	if (gsm->allow_duplicates == FALSE) {
-		GSList *l;
-
-		for (l = gsm->apns; l; l = l->next) {
-			struct ofono_gprs_provision_data *pd = l->data;
-
-			if (pd->type != ap->type)
-				continue;
-
-			mbpi_g_set_error(context, error, mbpi_error_quark(),
-						MBPI_ERROR_DUPLICATE,
-						"Duplicate context detected");
-
-			mbpi_ap_free(ap);
-			return;
-		}
-	}
-
-	gsm->apns = g_slist_append(gsm->apns, ap);
-}
-
-static const GMarkupParser gsm_parser = {
-	gsm_start,
-	gsm_end,
-	NULL,
-	NULL,
-	NULL,
-};
-
-static void toplevel_gsm_start(GMarkupParseContext *context,
-					const gchar *element_name,
-					const gchar **atribute_names,
-					const gchar **attribute_values,
-					gpointer userdata, GError **error)
-{
-	struct gsm_data *gsm = userdata;
-
-	if (g_str_equal(element_name, "gsm")) {
-		gsm->match_found = FALSE;
-		g_markup_parse_context_push(context, &gsm_parser, gsm);
-	} else if (g_str_equal(element_name, "cdma"))
-		g_markup_parse_context_push(context, &skip_parser, NULL);
-}
-
-static void toplevel_gsm_end(GMarkupParseContext *context,
-					const gchar *element_name,
-					gpointer userdata, GError **error)
-{
-	if (g_str_equal(element_name, "gsm") ||
-			g_str_equal(element_name, "cdma"))
-		g_markup_parse_context_pop(context);
-}
-
-static const GMarkupParser toplevel_gsm_parser = {
-	toplevel_gsm_start,
-	toplevel_gsm_end,
-	NULL,
-	NULL,
-	NULL,
-};
-
-static gboolean mbpi_parse(const GMarkupParser *parser, gpointer userdata,
-				GError **error)
-{
-	struct stat st;
-	char *db;
-	int fd;
-	GMarkupParseContext *context;
-	gboolean ret;
-
-	fd = open(MBPI_DATABASE, O_RDONLY);
-	if (fd < 0) {
-		g_set_error(error, G_FILE_ERROR,
-				g_file_error_from_errno(errno),
-				"open(%s) failed: %s", MBPI_DATABASE,
-				g_strerror(errno));
-		return FALSE;
-	}
-
-	if (fstat(fd, &st) < 0) {
-		close(fd);
-		g_set_error(error, G_FILE_ERROR,
-				g_file_error_from_errno(errno),
-				"fstat(%s) failed: %s", MBPI_DATABASE,
-				g_strerror(errno));
-		return FALSE;
-	}
-
-	db = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
-	if (db == MAP_FAILED) {
-		close(fd);
-		g_set_error(error, G_FILE_ERROR,
-				g_file_error_from_errno(errno),
-				"mmap(%s) failed: %s", MBPI_DATABASE,
-				g_strerror(errno));
-		return FALSE;
-	}
-
-	context = g_markup_parse_context_new(parser,
-						G_MARKUP_TREAT_CDATA_AS_TEXT,
-						userdata, NULL);
-
-	ret = g_markup_parse_context_parse(context, db, st.st_size, error);
-
-	if (ret == TRUE)
-		g_markup_parse_context_end_parse(context, error);
-
-	munmap(db, st.st_size);
-	close(fd);
-	g_markup_parse_context_free(context);
-
-	return ret;
-}
-
-GSList *mbpi_lookup_apn(const char *mcc, const char *mnc,
-			gboolean allow_duplicates, GError **error)
-{
-	struct gsm_data gsm;
-	GSList *l;
-
-	memset(&gsm, 0, sizeof(gsm));
-	gsm.match_mcc = mcc;
-	gsm.match_mnc = mnc;
-	gsm.allow_duplicates = allow_duplicates;
-
-	if (mbpi_parse(&toplevel_gsm_parser, &gsm, error) == FALSE) {
-		for (l = gsm.apns; l; l = l->next)
-			mbpi_ap_free(l->data);
-
-		g_slist_free(gsm.apns);
-		gsm.apns = NULL;
-	}
-
-	return gsm.apns;
-}
diff --git a/plugins/mbpi.h b/plugins/mbpi.h
deleted file mode 100644
index 6d343584..00000000
--- a/plugins/mbpi.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *
- *  oFono - Open Source Telephony
- *
- *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- *  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 General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-const char *mbpi_ap_type(enum ofono_gprs_context_type type);
-
-void mbpi_ap_free(struct ofono_gprs_provision_data *data);
-
-GSList *mbpi_lookup_apn(const char *mcc, const char *mnc,
-			gboolean allow_duplicates, GError **error);
diff --git a/plugins/provision.c b/plugins/provision.c
deleted file mode 100644
index 99c299eb..00000000
--- a/plugins/provision.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- *
- *  oFono - Open Source Telephony
- *
- *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- *  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 General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <errno.h>
-#include <string.h>
-
-#include <glib.h>
-
-#define OFONO_API_SUBJECT_TO_CHANGE
-#include <ofono/types.h>
-#include <ofono/log.h>
-#include <ofono/plugin.h>
-#include <ofono/modem.h>
-#include <ofono/gprs-provision.h>
-
-#include "mbpi.h"
-
-static int provision_get_settings(const char *mcc, const char *mnc,
-				const char *spn,
-				struct ofono_gprs_provision_data **settings,
-				int *count)
-{
-	GSList *l;
-	GSList *apns;
-	GError *error = NULL;
-	int ap_count;
-	int i;
-
-	DBG("Provisioning for MCC %s, MNC %s, SPN '%s'", mcc, mnc, spn);
-
-	apns = mbpi_lookup_apn(mcc, mnc, FALSE, &error);
-	if (apns == NULL) {
-		if (error != NULL) {
-			ofono_error("%s", error->message);
-			g_error_free(error);
-		}
-
-		return -ENOENT;
-	}
-
-	ap_count = g_slist_length(apns);
-
-	DBG("Found %d APs", ap_count);
-
-	*settings = g_try_new0(struct ofono_gprs_provision_data, ap_count);
-	if (*settings == NULL) {
-		ofono_error("Provisioning failed: %s", g_strerror(errno));
-
-		for (l = apns; l; l = l->next)
-			mbpi_ap_free(l->data);
-
-		g_slist_free(apns);
-
-		return -ENOMEM;
-	}
-
-	*count = ap_count;
-
-	for (l = apns, i = 0; l; l = l->next, i++) {
-		struct ofono_gprs_provision_data *ap = l->data;
-
-		DBG("Name: '%s'", ap->name);
-		DBG("APN: '%s'", ap->apn);
-		DBG("Type: %s", mbpi_ap_type(ap->type));
-		DBG("Username: '%s'", ap->username);
-		DBG("Password: '%s'", ap->password);
-
-		memcpy(*settings + i, ap,
-			sizeof(struct ofono_gprs_provision_data));
-
-		g_free(ap);
-	}
-
-	g_slist_free(apns);
-
-	return 0;
-}
-
-static struct ofono_gprs_provision_driver provision_driver = {
-	.name		= "Provisioning",
-	.get_settings	= provision_get_settings
-};
-
-static int provision_init(void)
-{
-	return ofono_gprs_provision_driver_register(&provision_driver);
-}
-
-static void provision_exit(void)
-{
-	ofono_gprs_provision_driver_unregister(&provision_driver);
-}
-
-OFONO_PLUGIN_DEFINE(provision, "Provisioning Plugin", VERSION,
-			OFONO_PLUGIN_PRIORITY_DEFAULT,
-			provision_init, provision_exit)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 13/15] examples: Remove provision example
  2023-12-19 18:36 [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
                   ` (10 preceding siblings ...)
  2023-12-19 18:37 ` [PATCH v2 12/15] plugins: provision: Remove mbpi support Denis Kenzior
@ 2023-12-19 18:37 ` Denis Kenzior
  2023-12-19 18:37 ` [PATCH v2 14/15] gprs-provision: Remove no longer used atom/driver Denis Kenzior
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2023-12-19 18:37 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

---
 Makefile.am          |   3 --
 examples/provision.c | 101 -------------------------------------------
 2 files changed, 104 deletions(-)
 delete mode 100644 examples/provision.c

diff --git a/Makefile.am b/Makefile.am
index 447f2466..1a97a1f1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -660,9 +660,6 @@ builtin_sources += examples/history.c
 builtin_modules += example_nettime
 builtin_sources += examples/nettime.c
 
-builtin_modules += example_provision
-builtin_sources += examples/provision.c
-
 builtin_modules += example_emulator
 builtin_sources += examples/emulator.c
 
diff --git a/examples/provision.c b/examples/provision.c
deleted file mode 100644
index 3f9d124f..00000000
--- a/examples/provision.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- *
- *  oFono - Open Source Telephony
- *
- *  Copyright (C) 2011  Nokia Corporation and/or its subsidiary(-ies).
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- *  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 General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <glib.h>
-
-#include <errno.h>
-
-#define OFONO_API_SUBJECT_TO_CHANGE
-
-#include <ofono/modem.h>
-#include <ofono/gprs-provision.h>
-#include <ofono/types.h>
-#include <ofono/plugin.h>
-#include <ofono/log.h>
-
-static int example_provision_get_settings(const char *mcc, const char *mnc,
-				const char *spn,
-				struct ofono_gprs_provision_data **settings,
-				int *count)
-{
-	ofono_debug("Provisioning...");
-	*count = 0;
-	*settings = NULL;
-
-	ofono_debug("Finding settings for MCC %s, MNC %s, SPN '%s'",
-			mcc, mnc, spn);
-
-	if (strcmp(mcc, "246") != 0 || strcmp(mnc, "81") != 0 ||
-						g_strcmp0(spn, "oFono") != 0)
-		return -ENOENT;
-
-	ofono_debug("Creating example settings for phonesim");
-
-	*settings = g_try_new0(struct ofono_gprs_provision_data, 2);
-	if (*settings == NULL)
-		return -ENOMEM;
-
-	*count = 2;
-
-	/* Internet context settings */
-	(*settings)[0].proto = OFONO_GPRS_PROTO_IP;
-	(*settings)[0].type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
-	(*settings)[0].name = g_strdup("Phonesim Internet");
-	(*settings)[0].apn = g_strdup("internetapn");
-
-	/* MMS context settings */
-	(*settings)[1].proto = OFONO_GPRS_PROTO_IP;
-	(*settings)[1].type = OFONO_GPRS_CONTEXT_TYPE_MMS;
-	(*settings)[1].name = g_strdup("Phonesim MMS");
-	(*settings)[1].apn = g_strdup("mmsapn");
-	(*settings)[1].username = g_strdup("mmsuser");
-	(*settings)[1].password = g_strdup("mmspass");
-	(*settings)[1].message_proxy = g_strdup("10.11.12.13:8080");
-	(*settings)[1].message_center = g_strdup("http://mms.example.com:8000");
-
-	return 0;
-}
-
-static struct ofono_gprs_provision_driver example_driver = {
-	.name		= "Example GPRS context provisioning",
-	.priority       = OFONO_PLUGIN_PRIORITY_LOW,
-	.get_settings	= example_provision_get_settings,
-};
-
-static int example_provision_init(void)
-{
-	return ofono_gprs_provision_driver_register(&example_driver);
-}
-
-static void example_provision_exit(void)
-{
-	ofono_gprs_provision_driver_unregister(&example_driver);
-}
-
-OFONO_PLUGIN_DEFINE(example_provision, "Example Provisioning Plugin",
-			VERSION, OFONO_PLUGIN_PRIORITY_DEFAULT,
-			example_provision_init,
-			example_provision_exit)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 14/15] gprs-provision: Remove no longer used atom/driver
  2023-12-19 18:36 [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
                   ` (11 preceding siblings ...)
  2023-12-19 18:37 ` [PATCH v2 13/15] examples: Remove provision example Denis Kenzior
@ 2023-12-19 18:37 ` Denis Kenzior
  2023-12-19 18:37 ` [PATCH v2 15/15] provision: Detect duplicates Denis Kenzior
  2024-01-02 17:18 ` [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
  14 siblings, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2023-12-19 18:37 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

---
 Makefile.am              |   2 +-
 include/gprs-provision.h |  13 -----
 src/gprs-provision.c     | 101 ---------------------------------------
 3 files changed, 1 insertion(+), 115 deletions(-)
 delete mode 100644 src/gprs-provision.c

diff --git a/Makefile.am b/Makefile.am
index 1a97a1f1..15d220f7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -702,7 +702,7 @@ src_ofonod_SOURCES = $(builtin_sources) $(gatchat_sources) src/ofono.ver \
 			src/simfs.c src/simfs.h src/audio-settings.c \
 			src/smsagent.c src/smsagent.h src/ctm.c \
 			src/sim-auth.c \
-			src/message.h src/message.c src/gprs-provision.c \
+			src/message.h src/message.c \
 			src/emulator.c src/location-reporting.c \
 			src/gnss.c \
 			src/gnssagent.c src/gnssagent.h \
diff --git a/include/gprs-provision.h b/include/gprs-provision.h
index 75808e66..ac0f5905 100644
--- a/include/gprs-provision.h
+++ b/include/gprs-provision.h
@@ -42,19 +42,6 @@ struct ofono_gprs_provision_data {
 	char *message_center;
 };
 
-struct ofono_gprs_provision_driver {
-	const char *name;
-	int priority;
-	int (*get_settings)(const char *mcc, const char *mnc, const char *spn,
-				struct ofono_gprs_provision_data **settings,
-				int *count);
-};
-
-int ofono_gprs_provision_driver_register(
-			const struct ofono_gprs_provision_driver *driver);
-void ofono_gprs_provision_driver_unregister(
-			const struct ofono_gprs_provision_driver *driver);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/gprs-provision.c b/src/gprs-provision.c
deleted file mode 100644
index 011d5a8d..00000000
--- a/src/gprs-provision.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- *
- *  oFono - Open Source Telephony
- *
- *  Copyright (C) 2011  Nokia Corporation and/or its subsidiary(-ies).
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- *  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 General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <glib.h>
-#include "ofono.h"
-
-static GSList *g_drivers = NULL;
-
-void  __ofono_gprs_provision_free_settings(
-				struct ofono_gprs_provision_data *settings,
-				int count)
-{
-	int i;
-
-	for (i = 0; i < count; i++) {
-		g_free(settings[i].name);
-		g_free(settings[i].apn);
-		g_free(settings[i].username);
-		g_free(settings[i].password);
-		g_free(settings[i].message_proxy);
-		g_free(settings[i].message_center);
-	}
-
-	g_free(settings);
-}
-
-ofono_bool_t __ofono_gprs_provision_get_settings(const char *mcc,
-				const char *mnc, const char *spn,
-				struct ofono_gprs_provision_data **settings,
-				int *count)
-{
-	GSList *d;
-
-	if (mcc == NULL || strlen(mcc) == 0 || mnc == NULL || strlen(mnc) == 0)
-		return FALSE;
-
-	for (d = g_drivers; d != NULL; d = d->next) {
-		const struct ofono_gprs_provision_driver *driver = d->data;
-
-		if (driver->get_settings == NULL)
-			continue;
-
-		DBG("Calling provisioning plugin '%s'", driver->name);
-
-		if (driver->get_settings(mcc, mnc, spn, settings, count) < 0)
-			continue;
-
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-static gint compare_priority(gconstpointer a, gconstpointer b)
-{
-	const struct ofono_gprs_provision_driver *plugin1 = a;
-	const struct ofono_gprs_provision_driver *plugin2 = b;
-
-	return plugin2->priority - plugin1->priority;
-}
-
-int ofono_gprs_provision_driver_register(
-			const struct ofono_gprs_provision_driver *driver)
-{
-	DBG("driver: %p name: %s", driver, driver->name);
-
-	g_drivers = g_slist_insert_sorted(g_drivers, (void *) driver,
-						compare_priority);
-	return 0;
-}
-
-void ofono_gprs_provision_driver_unregister(
-			const struct ofono_gprs_provision_driver *driver)
-{
-	DBG("driver: %p name: %s", driver, driver->name);
-
-	g_drivers = g_slist_remove(g_drivers, driver);
-}
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 15/15] provision: Detect duplicates
  2023-12-19 18:36 [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
                   ` (12 preceding siblings ...)
  2023-12-19 18:37 ` [PATCH v2 14/15] gprs-provision: Remove no longer used atom/driver Denis Kenzior
@ 2023-12-19 18:37 ` Denis Kenzior
  2024-01-02 17:18 ` [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
  14 siblings, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2023-12-19 18:37 UTC (permalink / raw)
  To: ofono; +Cc: Denis Kenzior

Duplicate contexts can't really be handled without user intervention, in
which case it is better to fail provisioning entirely.  Most vendors
will choose to ship a custom provisioning database to ensure that
duplicate contexts do not happen for the supported operators.
---
 src/provision.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/src/provision.c b/src/provision.c
index e419d15c..cd5cf569 100644
--- a/src/provision.c
+++ b/src/provision.c
@@ -25,6 +25,7 @@ bool __ofono_provision_get_settings(const char *mcc,
 	struct ofono_gprs_provision_data *contexts;
 	int r;
 	size_t i;
+	uint32_t type;
 
 	if (mcc == NULL || strlen(mcc) == 0 || mnc == NULL || strlen(mnc) == 0)
 		return false;
@@ -47,6 +48,20 @@ bool __ofono_provision_get_settings(const char *mcc,
 					ap->message_center);
 	}
 
+	/* Make sure there are no duplicates */
+	for (i = 0, type = 0; i < n_contexts; i++) {
+		struct ofono_gprs_provision_data *ap = contexts + i;
+
+		if (type & ap->type) {
+			ofono_warn("Duplicate detected for %s%s, spn: %s",
+					mcc, mnc, spn);
+			l_free(contexts);
+			return false;
+		}
+
+		type |= ap->type;
+	}
+
 	*count = n_contexts;
 	*settings = contexts;
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check
  2023-12-19 18:36 [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
                   ` (13 preceding siblings ...)
  2023-12-19 18:37 ` [PATCH v2 15/15] provision: Detect duplicates Denis Kenzior
@ 2024-01-02 17:18 ` Denis Kenzior
  14 siblings, 0 replies; 16+ messages in thread
From: Denis Kenzior @ 2024-01-02 17:18 UTC (permalink / raw)
  To: ofono

On 12/19/23 12:36, Denis Kenzior wrote:
> ---
>   acinclude.m4 | 3 +--
>   1 file changed, 1 insertion(+), 2 deletions(-)
> 

I went ahead and applied this build patch from this series

Regards,
-Denis


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2024-01-02 17:18 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-19 18:36 [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior
2023-12-19 18:36 ` [PATCH v2 02/15] include: Allow multiple context types Denis Kenzior
2023-12-19 18:37 ` [PATCH v2 03/15] module: Add support for ofono modules Denis Kenzior
2023-12-19 18:37 ` [PATCH v2 04/15] doc: docs for intermediate provisioning db format Denis Kenzior
2023-12-19 18:37 ` [PATCH v2 05/15] tools: Add provision.py Denis Kenzior
2023-12-19 18:37 ` [PATCH v2 06/15] core: Add utilities to read the provisioning db Denis Kenzior
2023-12-19 18:37 ` [PATCH v2 07/15] tools: lookup-apn: Use the new provision_db utils Denis Kenzior
2023-12-19 18:37 ` [PATCH v2 08/15] provision: Import initial JSON db Denis Kenzior
2023-12-19 18:37 ` [PATCH v2 09/15] provision: Add new module Denis Kenzior
2023-12-19 18:37 ` [PATCH v2 10/15] gprs: Use the new provisioning module Denis Kenzior
2023-12-19 18:37 ` [PATCH v2 11/15] plugins: Remove support for file-provision plugin Denis Kenzior
2023-12-19 18:37 ` [PATCH v2 12/15] plugins: provision: Remove mbpi support Denis Kenzior
2023-12-19 18:37 ` [PATCH v2 13/15] examples: Remove provision example Denis Kenzior
2023-12-19 18:37 ` [PATCH v2 14/15] gprs-provision: Remove no longer used atom/driver Denis Kenzior
2023-12-19 18:37 ` [PATCH v2 15/15] provision: Detect duplicates Denis Kenzior
2024-01-02 17:18 ` [PATCH v2 01/15] build: Fix typo that breaks --fsanitize=leak check Denis Kenzior

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).