[PATCH 2/2] rilmodem: Add IPv6 support in gprs-context
by Nishanth V
---
drivers/rilmodem/gprs-context.c | 251 +++++++++++++++++++++++++++++++++++-----
1 file changed, 225 insertions(+), 26 deletions(-)
diff --git a/drivers/rilmodem/gprs-context.c b/drivers/rilmodem/gprs-context.c
index 1e5f6ed..558231e 100644
--- a/drivers/rilmodem/gprs-context.c
+++ b/drivers/rilmodem/gprs-context.c
@@ -142,6 +142,217 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
}
}
+static int gprs_context_set_dns_servers(struct ofono_gprs_context *gc,
+ enum ofono_gprs_proto protocol,
+ char **dns_addrs)
+{
+ char **dns_ipv4_addrs, **dns_ipv6_addrs;
+ int proto;
+ int ipv4_idx, ipv6_idx;
+ int dns_strv_len;
+ int i;
+
+ if (protocol == OFONO_GPRS_PROTO_IP) {
+ ofono_gprs_context_set_ipv4_dns_servers(gc,
+ (const char **) dns_addrs);
+ return 0;
+ }
+
+ if (protocol == OFONO_GPRS_PROTO_IPV6) {
+ ofono_gprs_context_set_ipv6_dns_servers(gc,
+ (const char **) dns_addrs);
+ return 0;
+ }
+
+ dns_strv_len = g_strv_length(dns_addrs);
+
+ dns_ipv4_addrs = g_new0(char *, dns_strv_len + 1);
+ dns_ipv6_addrs = g_new0(char *, dns_strv_len + 1);
+
+ for (i = 0, ipv4_idx = 0, ipv6_idx = 0; dns_addrs[i]; i++) {
+ proto = ril_util_address_to_gprs_proto(dns_addrs[i]);
+
+ if (proto == OFONO_GPRS_PROTO_IP)
+ dns_ipv4_addrs[ipv4_idx++] = dns_addrs[i];
+
+ else if (proto == OFONO_GPRS_PROTO_IPV6)
+ dns_ipv6_addrs[ipv6_idx++] = dns_addrs[i];
+ }
+
+ if (ipv4_idx)
+ ofono_gprs_context_set_ipv4_dns_servers(gc,
+ (const char **) dns_ipv4_addrs);
+
+ if (ipv6_idx)
+ ofono_gprs_context_set_ipv6_dns_servers(gc,
+ (const char **) dns_ipv6_addrs);
+
+ g_free(dns_ipv4_addrs);
+ g_free(dns_ipv6_addrs);
+
+ return 0;
+}
+
+static int gprs_context_set_gateway(struct ofono_gprs_context *gc,
+ enum ofono_gprs_proto protocol,
+ char **gateways)
+{
+ int proto;
+ gboolean ipv4_flag, ipv6_flag;
+ int i;
+
+ if (protocol == OFONO_GPRS_PROTO_IP) {
+ ofono_gprs_context_set_ipv4_gateway(gc, gateways[0]);
+
+ return 0;
+ }
+
+ if (protocol == OFONO_GPRS_PROTO_IPV6) {
+ ofono_gprs_context_set_ipv6_gateway(gc, gateways[0]);
+
+ return 0;
+ }
+
+ ipv4_flag = FALSE;
+ ipv6_flag = FALSE;
+
+ for (i = 0; gateways[i]; i++) {
+ proto = ril_util_address_to_gprs_proto(gateways[i]);
+
+ if (!ipv4_flag && proto == OFONO_GPRS_PROTO_IP) {
+ ofono_gprs_context_set_ipv4_gateway(gc, gateways[i]);
+
+ ipv4_flag = TRUE;
+
+ } else if (!ipv6_flag && proto == OFONO_GPRS_PROTO_IPV6) {
+ ofono_gprs_context_set_ipv6_gateway(gc, gateways[i]);
+
+ ipv6_flag = TRUE;
+ }
+
+ /*
+ * both IPv4 and IPv6 gateways
+ * have been set, job done
+ */
+ if (ipv4_flag && ipv6_flag)
+ break;
+ }
+
+ return 0;
+}
+
+static int gprs_context_set_ipv4_address(struct ofono_gprs_context *gc,
+ const char *addrs)
+{
+ char **split_addrs = g_strsplit(addrs, "/", 2);
+ char *netmask;
+
+ /*
+ * Note - the address may optionally include a prefix size
+ * ( Eg. "/30" ). As this confuses NetworkManager, we
+ * explicitly strip any prefix after calculating the netmask
+ */
+ if (split_addrs == NULL || g_strv_length(split_addrs) == 0) {
+ g_strfreev(split_addrs);
+ return -1;
+ }
+
+ netmask = ril_util_get_netmask(addrs);
+
+ if (netmask)
+ ofono_gprs_context_set_ipv4_netmask(gc, netmask);
+
+ ofono_gprs_context_set_ipv4_address(gc, split_addrs[0], TRUE);
+
+ g_strfreev(split_addrs);
+
+ return 0;
+}
+
+static int gprs_context_set_ipv6_address(struct ofono_gprs_context *gc,
+ const char *addrs)
+{
+ char **split_addrs = g_strsplit(addrs, "/", 2);
+ guint64 prefix_ull;
+ char *endptr;
+ unsigned char prefix;
+
+ if (split_addrs == NULL || g_strv_length(split_addrs) == 0) {
+ g_strfreev(split_addrs);
+ return -1;
+ }
+
+ ofono_gprs_context_set_ipv6_address(gc, split_addrs[0]);
+
+ /*
+ * We will set ipv6 prefix length if present
+ * otherwise let connection manager decide
+ */
+ if (!split_addrs[1]) {
+ g_strfreev(split_addrs);
+ return 0;
+ }
+
+ prefix_ull = g_ascii_strtoull(split_addrs[1], &endptr, 10);
+
+ /* Discard in case of conversion failure or invalid prefix length */
+ if (split_addrs[1] == endptr || *endptr != '\0' || prefix_ull > 128) {
+ g_strfreev(split_addrs);
+ return -1;
+ }
+
+ prefix = prefix_ull;
+
+ ofono_gprs_context_set_ipv6_prefix_length(gc, prefix);
+
+ g_strfreev(split_addrs);
+
+ return 0;
+}
+
+static int gprs_context_set_address(struct ofono_gprs_context *gc,
+ enum ofono_gprs_proto protocol,
+ char **ip_addrs)
+{
+ int proto;
+ gboolean ipv4_flag, ipv6_flag;
+ int i;
+
+ if (protocol == OFONO_GPRS_PROTO_IP)
+ return gprs_context_set_ipv4_address(gc, ip_addrs[0]);
+
+ if (protocol == OFONO_GPRS_PROTO_IPV6)
+ return gprs_context_set_ipv6_address(gc, ip_addrs[0]);
+
+ ipv4_flag = FALSE;
+ ipv6_flag = FALSE;
+
+ for (i = 0; ip_addrs[i]; i++) {
+ proto = ril_util_address_to_gprs_proto(ip_addrs[i]);
+
+ if (!ipv4_flag && proto == OFONO_GPRS_PROTO_IP) {
+ if (gprs_context_set_ipv4_address(gc,
+ ip_addrs[i]) != 0)
+ return -1;
+
+ ipv4_flag = TRUE;
+
+ } else if (!ipv6_flag &&
+ proto == OFONO_GPRS_PROTO_IPV6) {
+ if (gprs_context_set_ipv6_address(gc,
+ ip_addrs[i]) != 0)
+ return -1;
+
+ ipv6_flag = TRUE;
+ }
+
+ if (ipv4_flag && ipv6_flag)
+ break;
+ }
+
+ return 0;
+}
+
static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
{
struct cb_data *cbd = user_data;
@@ -238,8 +449,12 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
goto error_free;
}
- ofono_gprs_context_set_ipv4_dns_servers(gc,
- (const char **) dns_addrs);
+ if (gprs_context_set_dns_servers(gc,
+ protocol, dns_addrs) != 0) {
+ g_strfreev(dns_addrs);
+ goto error_free;
+ }
+
g_strfreev(dns_addrs);
}
@@ -256,7 +471,11 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
goto error_free;
}
- ofono_gprs_context_set_ipv4_gateway(gc, gateways[0]);
+ if (gprs_context_set_gateway(gc, protocol, gateways) != 0) {
+ g_strfreev(gateways);
+ goto error_free;
+ }
+
g_strfreev(gateways);
} else
goto error_free;
@@ -274,8 +493,6 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
*/
if (raw_addrs) {
char **ip_addrs = g_strsplit(raw_addrs, " ", 3);
- char **split_ip_addr;
- char *netmask;
if (ip_addrs == NULL || g_strv_length(ip_addrs) == 0) {
g_strfreev(ip_addrs);
@@ -284,30 +501,12 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
goto error_free;
}
- if (g_strv_length(ip_addrs) > 1)
- ofono_warn("%s: more than one IP addr returned: %s",
- __func__, raw_addrs);
- /*
- * Note - the address may optionally include a prefix size
- * ( Eg. "/30" ). As this confuses NetworkManager, we
- * explicitly strip any prefix after calculating the netmask
- */
- split_ip_addr = g_strsplit(ip_addrs[0], "/", 2);
-
- netmask = ril_util_get_netmask(ip_addrs[0]);
-
- g_strfreev(ip_addrs);
-
- if (split_ip_addr == NULL ||
- g_strv_length(split_ip_addr) == 0) {
- g_strfreev(split_ip_addr);
+ if (gprs_context_set_address(gc, protocol, ip_addrs) != 0) {
+ g_strfreev(ip_addrs);
goto error_free;
}
- if (netmask)
- ofono_gprs_context_set_ipv4_netmask(gc, netmask);
-
- ofono_gprs_context_set_ipv4_address(gc, split_ip_addr[0], TRUE);
+ g_strfreev(ip_addrs);
}
g_free(type);
--
1.9.1
4 years, 12 months
[PATCH 1/2] rilmodem: Add address to protocol type util func
by Nishanth V
---
drivers/rilmodem/rilutil.c | 27 +++++++++++++++++++++++++++
drivers/rilmodem/rilutil.h | 2 ++
2 files changed, 29 insertions(+)
diff --git a/drivers/rilmodem/rilutil.c b/drivers/rilmodem/rilutil.c
index 44e5a9c..6cdce9a 100644
--- a/drivers/rilmodem/rilutil.c
+++ b/drivers/rilmodem/rilutil.c
@@ -28,6 +28,7 @@
#include <gril.h>
#include <string.h>
#include <stdlib.h>
+#include <arpa/inet.h>
#define OFONO_API_SUBJECT_TO_CHANGE
#include <ofono/log.h>
@@ -132,3 +133,29 @@ int ril_util_registration_state_to_status(int reg_state)
return reg_state;
}
+
+int ril_util_address_to_gprs_proto(const char *addr)
+{
+ int ret = -1;
+ struct in_addr ipv4;
+ struct in6_addr ipv6;
+ char **addr_split = g_strsplit(addr, "/", 2);
+
+ if (addr_split == NULL || g_strv_length(addr_split) == 0)
+ goto done;
+
+ if (inet_pton(AF_INET, addr_split[0], &ipv4) > 0) {
+ ret = OFONO_GPRS_PROTO_IP;
+ goto done;
+ }
+
+ if (inet_pton(AF_INET6, addr_split[0], &ipv6) > 0) {
+ ret = OFONO_GPRS_PROTO_IPV6;
+ goto done;
+ }
+
+done:
+ g_strfreev(addr_split);
+
+ return ret;
+}
diff --git a/drivers/rilmodem/rilutil.h b/drivers/rilmodem/rilutil.h
index 0361801..1791cda 100644
--- a/drivers/rilmodem/rilutil.h
+++ b/drivers/rilmodem/rilutil.h
@@ -109,6 +109,8 @@ const char *ril_util_gprs_proto_to_ril_string(enum ofono_gprs_proto);
int ril_util_registration_state_to_status(int reg_state);
+int ril_util_address_to_gprs_proto(const char *addr);
+
#define DECLARE_FAILURE(e) \
struct ofono_error e; \
e.type = OFONO_ERROR_TYPE_FAILURE; \
--
1.9.1
4 years, 12 months
[PATCH] gprs-context: fix don't use default ipv4 netmask
by Nishanth V
---
drivers/rilmodem/gprs-context.c | 3 ++-
drivers/rilmodem/rilutil.c | 51 ++++++++++++++++-------------------------
2 files changed, 22 insertions(+), 32 deletions(-)
diff --git a/drivers/rilmodem/gprs-context.c b/drivers/rilmodem/gprs-context.c
index 2bc6445..1e5f6ed 100644
--- a/drivers/rilmodem/gprs-context.c
+++ b/drivers/rilmodem/gprs-context.c
@@ -304,7 +304,8 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
goto error_free;
}
- ofono_gprs_context_set_ipv4_netmask(gc, netmask);
+ if (netmask)
+ ofono_gprs_context_set_ipv4_netmask(gc, netmask);
ofono_gprs_context_set_ipv4_address(gc, split_ip_addr[0], TRUE);
}
diff --git a/drivers/rilmodem/rilutil.c b/drivers/rilmodem/rilutil.c
index dc9c3cc..44e5a9c 100644
--- a/drivers/rilmodem/rilutil.c
+++ b/drivers/rilmodem/rilutil.c
@@ -52,39 +52,28 @@ void decode_ril_error(struct ofono_error *error, const char *final)
gchar *ril_util_get_netmask(const gchar *address)
{
- char *result;
-
- if (g_str_has_suffix(address, "/30")) {
- result = PREFIX_30_NETMASK;
- } else if (g_str_has_suffix(address, "/29")) {
- result = PREFIX_29_NETMASK;
- } else if (g_str_has_suffix(address, "/28")) {
- result = PREFIX_28_NETMASK;
- } else if (g_str_has_suffix(address, "/27")) {
- result = PREFIX_27_NETMASK;
- } else if (g_str_has_suffix(address, "/26")) {
- result = PREFIX_26_NETMASK;
- } else if (g_str_has_suffix(address, "/25")) {
- result = PREFIX_25_NETMASK;
- } else if (g_str_has_suffix(address, "/24")) {
- result = PREFIX_24_NETMASK;
- } else {
- /*
- * This handles the case where the
- * Samsung RILD returns an address without
- * a prefix, however it explicitly sets a
- * /24 netmask ( which isn't returned as
- * an attribute of the DATA_CALL.
- *
- * TODO/OEM: this might need to be quirked
- * for specific devices.
- */
- result = PREFIX_24_NETMASK;
- }
+ if (g_str_has_suffix(address, "/30"))
+ return PREFIX_30_NETMASK;
+
+ if (g_str_has_suffix(address, "/29"))
+ return PREFIX_29_NETMASK;
+
+ if (g_str_has_suffix(address, "/28"))
+ return PREFIX_28_NETMASK;
+
+ if (g_str_has_suffix(address, "/27"))
+ return PREFIX_27_NETMASK;
+
+ if (g_str_has_suffix(address, "/26"))
+ return PREFIX_26_NETMASK;
+
+ if (g_str_has_suffix(address, "/25"))
+ return PREFIX_25_NETMASK;
- DBG("address: %s netmask: %s", address, result);
+ if (g_str_has_suffix(address, "/24"))
+ return PREFIX_24_NETMASK;
- return result;
+ return NULL;
}
void ril_util_build_deactivate_data_call(GRil *gril, struct parcel *rilp,
--
1.9.1
4 years, 12 months
[PATCH 1/4] doc: Add allowed-apns api doc
by Nishanth V
---
Makefile.am | 3 ++-
doc/allowed-apns-api.txt | 17 +++++++++++++++++
2 files changed, 19 insertions(+), 1 deletion(-)
create mode 100644 doc/allowed-apns-api.txt
diff --git a/Makefile.am b/Makefile.am
index 5cd9766..f1a89cc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -646,7 +646,8 @@ doc_files = doc/overview.txt doc/ofono-paper.txt doc/release-faq.txt \
doc/location-reporting-api.txt \
doc/certification.txt doc/siri-api.txt \
doc/telit-modem.txt \
- doc/networkmonitor-api.txt
+ doc/networkmonitor-api.txt \
+ doc/allowed-apns-api.txt
test_scripts = test/backtrace \
diff --git a/doc/allowed-apns-api.txt b/doc/allowed-apns-api.txt
new file mode 100644
index 0000000..6bc95d0
--- /dev/null
+++ b/doc/allowed-apns-api.txt
@@ -0,0 +1,17 @@
+Allowed APNs hierarchy
+=========================
+
+Service org.ofono
+Interface org.ofono.AllowedAccessPoints
+Object path [variable prefix]/{modem0,modem1,...}
+
+Methods array{string} GetAllowedAccessPoints()
+
+ Get the list of allowed access points provided
+ in the SIM card.
+
+ This method returns an array of strings which
+ contains a list of Access Point Names supported
+ by network provider. Returns with an error if
+ SIM reading failed or an empty list if there
+ are no access points listed on the SIM.
--
1.9.1
4 years, 12 months
HFP support
by Alexandre Da Costa
Hi all,
I've been using bluez, ofono and pulseaudio for bluetooth audio tests for a
few months. While everything worked fine with bluez 4, I've the need to
include BLE tests which require bluez 5.
This leads to quite some changes regarding HSP and HFP. My main requirement
is to test a bluetooth headset. Using pulseaudio with its native HSP
support I can have audio both ways from and to my headset. As I would like
to include the telephony features, I'm trying to move to ofono and HFP.
I've not found the current status of ofono and its HFP support. What use
cases are currently supported (audio gateway and/or headset) ? I tried to
configure pulseaudio to use ofono as HFP agent but I keep receiving the
following message when switch from A2DH to HFP : "Refused to switch profile
to headset_head_unit: Not connected"
Is there any limitation or am I missing something ?
Thanks
4 years, 12 months
[PATCH 4/4] test: Add list allowed access points script
by Nishanth V
---
Makefile.am | 3 ++-
test/list-allowed-access-points | 25 +++++++++++++++++++++++++
2 files changed, 27 insertions(+), 1 deletion(-)
create mode 100755 test/list-allowed-access-points
diff --git a/Makefile.am b/Makefile.am
index c788149..5215b2e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -749,7 +749,8 @@ test_scripts = test/backtrace \
test/register-operator \
test/set-sms-smsc \
test/set-sms-bearer \
- test/get-serving-cell-info
+ test/get-serving-cell-info \
+ test/list-allowed-access-points
if TEST
testdir = $(pkglibdir)/test
diff --git a/test/list-allowed-access-points b/test/list-allowed-access-points
new file mode 100755
index 0000000..c7bb50c
--- /dev/null
+++ b/test/list-allowed-access-points
@@ -0,0 +1,25 @@
+#!/usr/bin/python3
+
+import dbus
+
+bus = dbus.SystemBus()
+
+manager = dbus.Interface(bus.get_object('org.ofono', '/'),
+ 'org.ofono.Manager')
+
+modems = manager.GetModems()
+
+for path, properties in modems:
+ if "org.ofono.AllowedAccessPoints" not in properties["Interfaces"]:
+ continue
+
+ allowedAccessPoints = dbus.Interface(bus.get_object('org.ofono',
+ path), 'org.ofono.AllowedAccessPoints')
+
+ apns = allowedAccessPoints.GetAllowedAccessPoints()
+
+ print("Allowed Access Points for [ %s ]" % (path))
+ for apn in apns:
+ print(" [ %s]" % (apn))
+
+print("")
--
1.9.1
4 years, 12 months
[PATCH 3/4] plugins: Add allowed apn list
by Nishanth V
---
Makefile.am | 3 +
plugins/allowed-apns.c | 272 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 275 insertions(+)
create mode 100644 plugins/allowed-apns.c
diff --git a/Makefile.am b/Makefile.am
index f1a89cc..c788149 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -572,6 +572,9 @@ builtin_sources += plugins/smart-messaging.c
builtin_modules += push_notification
builtin_sources += plugins/push-notification.c
+builtin_modules += allowed_apns
+builtin_sources += plugins/allowed-apns.c
+
sbin_PROGRAMS = src/ofonod
src_ofonod_SOURCES = $(builtin_sources) $(gatchat_sources) src/ofono.ver \
diff --git a/plugins/allowed-apns.c b/plugins/allowed-apns.c
new file mode 100644
index 0000000..77ede86
--- /dev/null
+++ b/plugins/allowed-apns.c
@@ -0,0 +1,272 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2016 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 <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <glib.h>
+#include <ofono.h>
+#include <simutil.h>
+
+#define OFONO_API_SUBJECT_TO_CHANGE
+#include <ofono/plugin.h>
+#include <ofono/log.h>
+#include <ofono/modem.h>
+#include <ofono/sim.h>
+#include <ofono/dbus.h>
+#include <gdbus.h>
+
+#define SIM_EFACL_FILEID 0x6f57
+
+#define ALLOWED_ACCESS_POINTS_INTERFACE "org.ofono.AllowedAccessPoints"
+
+guint modemwatch_id;
+
+struct allowed_apns_ctx {
+ guint simwatch_id;
+ guint atomwatch_id;
+ struct ofono_modem *modem;
+ struct ofono_sim *sim;
+ struct ofono_sim_context *sim_context;
+ DBusMessage *pending;
+ DBusMessage *reply;
+};
+
+GSList *context_list;
+
+static void context_destroy(gpointer data)
+{
+ struct allowed_apns_ctx *ctx = data;
+
+ if (ctx->simwatch_id)
+ ofono_sim_remove_state_watch(ctx->sim,
+ ctx->simwatch_id);
+
+ if (ctx->atomwatch_id)
+ __ofono_modem_remove_atom_watch(ctx->modem,
+ ctx->atomwatch_id);
+
+ if (ctx->sim_context)
+ ofono_sim_context_free(ctx->sim_context);
+
+ context_list = g_slist_remove(context_list, ctx);
+
+ g_free(ctx);
+}
+
+static void sim_acl_read_cb(int ok, int total_length, int record,
+ const unsigned char *data, int record_length,
+ void *userdata)
+{
+ struct allowed_apns_ctx *ctx = userdata;
+ DBusMessage *reply = ctx->reply;
+ DBusMessageIter iter;
+ DBusMessageIter array;
+ struct simple_tlv_iter tlv_iter;
+ char *apn;
+
+ if (!ok) {
+ reply = __ofono_error_failed(ctx->pending);
+ __ofono_dbus_pending_reply(&ctx->pending, reply);
+ return;
+ }
+
+ reply = dbus_message_new_method_return(ctx->pending);
+ if (reply == NULL)
+ return;
+
+ dbus_message_iter_init_append(reply, &iter);
+
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING,
+ &array);
+
+ if (data[0] == 0)
+ goto done;
+
+ simple_tlv_iter_init(&tlv_iter, &data[1], total_length - 1);
+
+ while (simple_tlv_iter_next(&tlv_iter)) {
+ if (simple_tlv_iter_get_tag(&tlv_iter) != 0xDD)
+ continue;
+
+ apn = g_strndup(
+ (char *) simple_tlv_iter_get_data(&tlv_iter),
+ simple_tlv_iter_get_length(&tlv_iter));
+
+ dbus_message_iter_append_basic(&array,
+ DBUS_TYPE_STRING,
+ &apn);
+
+ g_free(apn);
+ }
+
+done:
+ dbus_message_iter_close_container(&iter, &array);
+
+ __ofono_dbus_pending_reply(&ctx->pending, reply);
+}
+
+static DBusMessage *get_allowed_apns(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct allowed_apns_ctx *ctx = data;
+
+ if (ctx->pending)
+ return __ofono_error_busy(msg);
+
+ ctx->pending = dbus_message_ref(msg);
+
+ ofono_sim_read(ctx->sim_context, SIM_EFACL_FILEID,
+ OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
+ sim_acl_read_cb, ctx);
+
+ return NULL;
+}
+
+static const GDBusMethodTable allowed_apns_methods[] = {
+ { GDBUS_ASYNC_METHOD("GetAllowedAccessPoints",
+ NULL, GDBUS_ARGS({ "apnlist", "as" }),
+ get_allowed_apns) },
+ { }
+};
+
+static void sim_state_watch(enum ofono_sim_state new_state, void *data)
+{
+ struct allowed_apns_ctx *ctx = data;
+ DBusConnection *conn = ofono_dbus_get_connection();
+
+ if (new_state != OFONO_SIM_STATE_READY) {
+ g_dbus_unregister_interface(conn,
+ ofono_modem_get_path(ctx->modem),
+ ALLOWED_ACCESS_POINTS_INTERFACE);
+
+ ofono_modem_remove_interface(ctx->modem,
+ ALLOWED_ACCESS_POINTS_INTERFACE);
+
+ return;
+ }
+
+ if (!g_dbus_register_interface(conn,
+ ofono_modem_get_path(ctx->modem),
+ ALLOWED_ACCESS_POINTS_INTERFACE,
+ allowed_apns_methods, NULL, NULL,
+ ctx, NULL)) {
+ ofono_error("Cannot create %s Interface\n",
+ ALLOWED_ACCESS_POINTS_INTERFACE);
+
+ return;
+ }
+
+ ofono_modem_add_interface(ctx->modem,
+ ALLOWED_ACCESS_POINTS_INTERFACE);
+}
+
+static void sim_watch(struct ofono_atom *atom,
+ enum ofono_atom_watch_condition cond,
+ void *data)
+{
+ struct allowed_apns_ctx *ctx = data;
+
+ if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
+ if (ctx->sim_context)
+ ofono_sim_context_free(ctx->sim_context);
+
+ return;
+ }
+
+ ctx->sim = __ofono_atom_get_data(atom);
+
+ ctx->sim_context = ofono_sim_context_create(ctx->sim);
+
+ ctx->simwatch_id = ofono_sim_add_state_watch(ctx->sim,
+ sim_state_watch,
+ ctx, NULL);
+}
+
+static gint context_list_modem_compare(gconstpointer data1,
+ gconstpointer data2)
+{
+ const struct allowed_apns_ctx *ctx = data1;
+ const struct ofono_modem *modem = data2;
+ return (ctx->modem == modem);
+}
+
+static void modem_watch(struct ofono_modem *modem,
+ gboolean added, void *userdata)
+{
+ struct allowed_apns_ctx *ctx;
+ GSList *l;
+
+ if (added == FALSE) {
+ l = g_slist_find_custom(context_list,
+ modem, context_list_modem_compare);
+
+ if (l) {
+ ctx = l->data;
+ context_destroy(ctx);
+ context_list = g_slist_delete_link(context_list, l);
+ }
+
+ return;
+ }
+
+ ctx = g_try_new0(struct allowed_apns_ctx, 1);
+ if (ctx == NULL)
+ return;
+
+ context_list = g_slist_prepend(context_list, ctx);
+
+ ctx->modem = modem;
+
+ ctx->atomwatch_id = __ofono_modem_add_atom_watch(ctx->modem,
+ OFONO_ATOM_TYPE_SIM,
+ sim_watch, ctx, NULL);
+}
+
+static void call_modemwatch(struct ofono_modem *modem, void *userdata)
+{
+ modem_watch(modem, TRUE, userdata);
+}
+
+static int allowed_apns_init(void)
+{
+ modemwatch_id = __ofono_modemwatch_add(modem_watch, NULL, NULL);
+
+ __ofono_modem_foreach(call_modemwatch, NULL);
+
+ return 0;
+}
+
+static void allowed_apns_exit(void)
+{
+ __ofono_modemwatch_remove(modemwatch_id);
+
+ g_slist_free_full(context_list, context_destroy);
+}
+
+OFONO_PLUGIN_DEFINE(allowed_apns, "Plugin to read EFACL from SIM",
+ VERSION, OFONO_PLUGIN_PRIORITY_DEFAULT,
+ allowed_apns_init, allowed_apns_exit)
--
1.9.1
4 years, 12 months
[PATCH 2/4] simutil: Add EFACL in elementary file db
by Nishanth V
---
src/simutil.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/simutil.c b/src/simutil.c
index a7745ae..5f8c8b8 100644
--- a/src/simutil.c
+++ b/src/simutil.c
@@ -95,6 +95,7 @@ static struct sim_ef_info ef_db[] = {
{ 0x6F4D, 0x7F20, 0x7FFF, EF, RECORD, 0, PIN, PIN2 },
{ 0x6F50, 0x7F20, 0x7FFF, EF, BINARY, 0, PIN, PIN },
{ 0x6F56, 0x0000, 0x7FFF, EF, BINARY, 0, PIN, PIN2 },
+{ 0x6F57, 0x7F20, 0x7FFF, EF, BINARY, 0, PIN, PIN2 },
{ 0x6FAD, 0x7F20, 0x7FFF, EF, BINARY, 0, ALW, ADM },
{ 0x6FAE, 0x7F20, 0x0000, EF, BINARY, 1, ALW, ADM },
{ 0x6FB7, 0x7F20, 0x7FFF, EF, BINARY, 0, ALW, ADM },
--
1.9.1
4 years, 12 months
[PATCH] Fix crash when PUK is required
by caiwen.zhang@intel.com
From: Caiwen Zhang <caiwen.zhang(a)intel.com>
After input PIN wrong 3 times, sim main state (include spn_watches)
is freed. but the watch id still be kept by other atoms (network and
gprs), when remove the atom, it will try to remove the watch from
spn_watches, ofono daemon will crash.
---
src/sim.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/sim.c b/src/sim.c
index e1c1809..bcf5afd 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -1840,7 +1840,6 @@ static void sim_efphase_read_cb(int ok, int length, int record,
static void sim_initialize_after_pin(struct ofono_sim *sim)
{
sim->context = ofono_sim_context_create(sim);
- sim->spn_watches = __ofono_watchlist_new(g_free);
ofono_sim_read(sim->context, SIM_EFPHASE_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
@@ -2348,11 +2347,6 @@ static void sim_free_early_state(struct ofono_sim *sim)
static void sim_spn_close(struct ofono_sim *sim)
{
- if (sim->spn_watches) {
- __ofono_watchlist_free(sim->spn_watches);
- sim->spn_watches = NULL;
- }
-
/*
* We have not initialized SPN logic at all yet, either because
* no netreg / gprs atom has been needed or we have not reached the
@@ -2881,6 +2875,8 @@ static void sim_unregister(struct ofono_atom *atom)
__ofono_watchlist_free(sim->state_watches);
sim->state_watches = NULL;
+ __ofono_watchlist_free(sim->spn_watches);
+ sim->spn_watches = NULL;
g_dbus_unregister_interface(conn, path, OFONO_SIM_MANAGER_INTERFACE);
ofono_modem_remove_interface(modem, OFONO_SIM_MANAGER_INTERFACE);
@@ -3011,6 +3007,7 @@ void ofono_sim_register(struct ofono_sim *sim)
ofono_modem_add_interface(modem, OFONO_SIM_MANAGER_INTERFACE);
sim->state_watches = __ofono_watchlist_new(g_free);
+ sim->spn_watches = __ofono_watchlist_new(g_free);
sim->simfs = sim_fs_new(sim, sim->driver);
__ofono_atom_register(sim->atom, sim_unregister);
--
1.9.1
4 years, 12 months
[PATCH] plugins: Add allowed APN list
by Nishanth V
---
Makefile.am | 9 +-
doc/allowed-apns-api.txt | 17 +++
plugins/allowed-apns.c | 272 ++++++++++++++++++++++++++++++++++++++++
src/simutil.c | 1 +
test/list-allowed-access-points | 25 ++++
5 files changed, 322 insertions(+), 2 deletions(-)
create mode 100644 doc/allowed-apns-api.txt
create mode 100644 plugins/allowed-apns.c
create mode 100755 test/list-allowed-access-points
diff --git a/Makefile.am b/Makefile.am
index 5cd9766..5215b2e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -572,6 +572,9 @@ builtin_sources += plugins/smart-messaging.c
builtin_modules += push_notification
builtin_sources += plugins/push-notification.c
+builtin_modules += allowed_apns
+builtin_sources += plugins/allowed-apns.c
+
sbin_PROGRAMS = src/ofonod
src_ofonod_SOURCES = $(builtin_sources) $(gatchat_sources) src/ofono.ver \
@@ -646,7 +649,8 @@ doc_files = doc/overview.txt doc/ofono-paper.txt doc/release-faq.txt \
doc/location-reporting-api.txt \
doc/certification.txt doc/siri-api.txt \
doc/telit-modem.txt \
- doc/networkmonitor-api.txt
+ doc/networkmonitor-api.txt \
+ doc/allowed-apns-api.txt
test_scripts = test/backtrace \
@@ -745,7 +749,8 @@ test_scripts = test/backtrace \
test/register-operator \
test/set-sms-smsc \
test/set-sms-bearer \
- test/get-serving-cell-info
+ test/get-serving-cell-info \
+ test/list-allowed-access-points
if TEST
testdir = $(pkglibdir)/test
diff --git a/doc/allowed-apns-api.txt b/doc/allowed-apns-api.txt
new file mode 100644
index 0000000..6bc95d0
--- /dev/null
+++ b/doc/allowed-apns-api.txt
@@ -0,0 +1,17 @@
+Allowed APNs hierarchy
+=========================
+
+Service org.ofono
+Interface org.ofono.AllowedAccessPoints
+Object path [variable prefix]/{modem0,modem1,...}
+
+Methods array{string} GetAllowedAccessPoints()
+
+ Get the list of allowed access points provided
+ in the SIM card.
+
+ This method returns an array of strings which
+ contains a list of Access Point Names supported
+ by network provider. Returns with an error if
+ SIM reading failed or an empty list if there
+ are no access points listed on the SIM.
diff --git a/plugins/allowed-apns.c b/plugins/allowed-apns.c
new file mode 100644
index 0000000..77ede86
--- /dev/null
+++ b/plugins/allowed-apns.c
@@ -0,0 +1,272 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2016 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 <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <glib.h>
+#include <ofono.h>
+#include <simutil.h>
+
+#define OFONO_API_SUBJECT_TO_CHANGE
+#include <ofono/plugin.h>
+#include <ofono/log.h>
+#include <ofono/modem.h>
+#include <ofono/sim.h>
+#include <ofono/dbus.h>
+#include <gdbus.h>
+
+#define SIM_EFACL_FILEID 0x6f57
+
+#define ALLOWED_ACCESS_POINTS_INTERFACE "org.ofono.AllowedAccessPoints"
+
+guint modemwatch_id;
+
+struct allowed_apns_ctx {
+ guint simwatch_id;
+ guint atomwatch_id;
+ struct ofono_modem *modem;
+ struct ofono_sim *sim;
+ struct ofono_sim_context *sim_context;
+ DBusMessage *pending;
+ DBusMessage *reply;
+};
+
+GSList *context_list;
+
+static void context_destroy(gpointer data)
+{
+ struct allowed_apns_ctx *ctx = data;
+
+ if (ctx->simwatch_id)
+ ofono_sim_remove_state_watch(ctx->sim,
+ ctx->simwatch_id);
+
+ if (ctx->atomwatch_id)
+ __ofono_modem_remove_atom_watch(ctx->modem,
+ ctx->atomwatch_id);
+
+ if (ctx->sim_context)
+ ofono_sim_context_free(ctx->sim_context);
+
+ context_list = g_slist_remove(context_list, ctx);
+
+ g_free(ctx);
+}
+
+static void sim_acl_read_cb(int ok, int total_length, int record,
+ const unsigned char *data, int record_length,
+ void *userdata)
+{
+ struct allowed_apns_ctx *ctx = userdata;
+ DBusMessage *reply = ctx->reply;
+ DBusMessageIter iter;
+ DBusMessageIter array;
+ struct simple_tlv_iter tlv_iter;
+ char *apn;
+
+ if (!ok) {
+ reply = __ofono_error_failed(ctx->pending);
+ __ofono_dbus_pending_reply(&ctx->pending, reply);
+ return;
+ }
+
+ reply = dbus_message_new_method_return(ctx->pending);
+ if (reply == NULL)
+ return;
+
+ dbus_message_iter_init_append(reply, &iter);
+
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING,
+ &array);
+
+ if (data[0] == 0)
+ goto done;
+
+ simple_tlv_iter_init(&tlv_iter, &data[1], total_length - 1);
+
+ while (simple_tlv_iter_next(&tlv_iter)) {
+ if (simple_tlv_iter_get_tag(&tlv_iter) != 0xDD)
+ continue;
+
+ apn = g_strndup(
+ (char *) simple_tlv_iter_get_data(&tlv_iter),
+ simple_tlv_iter_get_length(&tlv_iter));
+
+ dbus_message_iter_append_basic(&array,
+ DBUS_TYPE_STRING,
+ &apn);
+
+ g_free(apn);
+ }
+
+done:
+ dbus_message_iter_close_container(&iter, &array);
+
+ __ofono_dbus_pending_reply(&ctx->pending, reply);
+}
+
+static DBusMessage *get_allowed_apns(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct allowed_apns_ctx *ctx = data;
+
+ if (ctx->pending)
+ return __ofono_error_busy(msg);
+
+ ctx->pending = dbus_message_ref(msg);
+
+ ofono_sim_read(ctx->sim_context, SIM_EFACL_FILEID,
+ OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
+ sim_acl_read_cb, ctx);
+
+ return NULL;
+}
+
+static const GDBusMethodTable allowed_apns_methods[] = {
+ { GDBUS_ASYNC_METHOD("GetAllowedAccessPoints",
+ NULL, GDBUS_ARGS({ "apnlist", "as" }),
+ get_allowed_apns) },
+ { }
+};
+
+static void sim_state_watch(enum ofono_sim_state new_state, void *data)
+{
+ struct allowed_apns_ctx *ctx = data;
+ DBusConnection *conn = ofono_dbus_get_connection();
+
+ if (new_state != OFONO_SIM_STATE_READY) {
+ g_dbus_unregister_interface(conn,
+ ofono_modem_get_path(ctx->modem),
+ ALLOWED_ACCESS_POINTS_INTERFACE);
+
+ ofono_modem_remove_interface(ctx->modem,
+ ALLOWED_ACCESS_POINTS_INTERFACE);
+
+ return;
+ }
+
+ if (!g_dbus_register_interface(conn,
+ ofono_modem_get_path(ctx->modem),
+ ALLOWED_ACCESS_POINTS_INTERFACE,
+ allowed_apns_methods, NULL, NULL,
+ ctx, NULL)) {
+ ofono_error("Cannot create %s Interface\n",
+ ALLOWED_ACCESS_POINTS_INTERFACE);
+
+ return;
+ }
+
+ ofono_modem_add_interface(ctx->modem,
+ ALLOWED_ACCESS_POINTS_INTERFACE);
+}
+
+static void sim_watch(struct ofono_atom *atom,
+ enum ofono_atom_watch_condition cond,
+ void *data)
+{
+ struct allowed_apns_ctx *ctx = data;
+
+ if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
+ if (ctx->sim_context)
+ ofono_sim_context_free(ctx->sim_context);
+
+ return;
+ }
+
+ ctx->sim = __ofono_atom_get_data(atom);
+
+ ctx->sim_context = ofono_sim_context_create(ctx->sim);
+
+ ctx->simwatch_id = ofono_sim_add_state_watch(ctx->sim,
+ sim_state_watch,
+ ctx, NULL);
+}
+
+static gint context_list_modem_compare(gconstpointer data1,
+ gconstpointer data2)
+{
+ const struct allowed_apns_ctx *ctx = data1;
+ const struct ofono_modem *modem = data2;
+ return (ctx->modem == modem);
+}
+
+static void modem_watch(struct ofono_modem *modem,
+ gboolean added, void *userdata)
+{
+ struct allowed_apns_ctx *ctx;
+ GSList *l;
+
+ if (added == FALSE) {
+ l = g_slist_find_custom(context_list,
+ modem, context_list_modem_compare);
+
+ if (l) {
+ ctx = l->data;
+ context_destroy(ctx);
+ context_list = g_slist_delete_link(context_list, l);
+ }
+
+ return;
+ }
+
+ ctx = g_try_new0(struct allowed_apns_ctx, 1);
+ if (ctx == NULL)
+ return;
+
+ context_list = g_slist_prepend(context_list, ctx);
+
+ ctx->modem = modem;
+
+ ctx->atomwatch_id = __ofono_modem_add_atom_watch(ctx->modem,
+ OFONO_ATOM_TYPE_SIM,
+ sim_watch, ctx, NULL);
+}
+
+static void call_modemwatch(struct ofono_modem *modem, void *userdata)
+{
+ modem_watch(modem, TRUE, userdata);
+}
+
+static int allowed_apns_init(void)
+{
+ modemwatch_id = __ofono_modemwatch_add(modem_watch, NULL, NULL);
+
+ __ofono_modem_foreach(call_modemwatch, NULL);
+
+ return 0;
+}
+
+static void allowed_apns_exit(void)
+{
+ __ofono_modemwatch_remove(modemwatch_id);
+
+ g_slist_free_full(context_list, context_destroy);
+}
+
+OFONO_PLUGIN_DEFINE(allowed_apns, "Plugin to read EFACL from SIM",
+ VERSION, OFONO_PLUGIN_PRIORITY_DEFAULT,
+ allowed_apns_init, allowed_apns_exit)
diff --git a/src/simutil.c b/src/simutil.c
index a7745ae..5f8c8b8 100644
--- a/src/simutil.c
+++ b/src/simutil.c
@@ -95,6 +95,7 @@ static struct sim_ef_info ef_db[] = {
{ 0x6F4D, 0x7F20, 0x7FFF, EF, RECORD, 0, PIN, PIN2 },
{ 0x6F50, 0x7F20, 0x7FFF, EF, BINARY, 0, PIN, PIN },
{ 0x6F56, 0x0000, 0x7FFF, EF, BINARY, 0, PIN, PIN2 },
+{ 0x6F57, 0x7F20, 0x7FFF, EF, BINARY, 0, PIN, PIN2 },
{ 0x6FAD, 0x7F20, 0x7FFF, EF, BINARY, 0, ALW, ADM },
{ 0x6FAE, 0x7F20, 0x0000, EF, BINARY, 1, ALW, ADM },
{ 0x6FB7, 0x7F20, 0x7FFF, EF, BINARY, 0, ALW, ADM },
diff --git a/test/list-allowed-access-points b/test/list-allowed-access-points
new file mode 100755
index 0000000..c7bb50c
--- /dev/null
+++ b/test/list-allowed-access-points
@@ -0,0 +1,25 @@
+#!/usr/bin/python3
+
+import dbus
+
+bus = dbus.SystemBus()
+
+manager = dbus.Interface(bus.get_object('org.ofono', '/'),
+ 'org.ofono.Manager')
+
+modems = manager.GetModems()
+
+for path, properties in modems:
+ if "org.ofono.AllowedAccessPoints" not in properties["Interfaces"]:
+ continue
+
+ allowedAccessPoints = dbus.Interface(bus.get_object('org.ofono',
+ path), 'org.ofono.AllowedAccessPoints')
+
+ apns = allowedAccessPoints.GetAllowedAccessPoints()
+
+ print("Allowed Access Points for [ %s ]" % (path))
+ for apn in apns:
+ print(" [ %s]" % (apn))
+
+print("")
--
1.9.1
4 years, 12 months