---
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