[-]
[+]
|
Changed |
_service:tar_git:ofono-1.17+git39.tar.bz2/ofono/drivers/ril/ril_gprs_context.c
^
|
@@ -42,7 +42,7 @@
struct ril_network *network;
struct ril_data *data;
guint active_ctx_cid;
- gulong calls_changed_event_id;
+ gulong calls_changed_id;
struct ril_mtu_watch *mtu_watch;
struct ril_data_call *active_call;
struct ril_gprs_context_call activate;
@@ -55,53 +55,32 @@
return ofono_gprs_context_get_data(gprs);
}
-static char *ril_gprs_context_netmask(const char *address)
+static char *ril_gprs_context_netmask(const char *bits)
{
- if (address) {
- const char *suffix = strchr(address, '/');
- if (suffix) {
- int nbits = atoi(suffix + 1);
- if (nbits > 0 && nbits < 33) {
- const char* str;
- struct in_addr in;
- in.s_addr = htonl((nbits == 32) ? 0xffffffff :
+ if (bits) {
+ int nbits = atoi(bits);
+ if (nbits > 0 && nbits < 33) {
+ const char* str;
+ struct in_addr in;
+ in.s_addr = htonl((nbits == 32) ? 0xffffffff :
((1 << nbits)-1) << (32-nbits));
- str = inet_ntoa(in);
- if (str) {
- return g_strdup(str);
- }
+ str = inet_ntoa(in);
+ if (str) {
+ return g_strdup(str);
}
}
}
- return g_strdup("255.255.255.0");
-}
-
-static void ril_gprs_context_set_ipv4(struct ofono_gprs_context *gc,
- char * const *ip_addr)
-{
- const guint n = gutil_strv_length(ip_addr);
-
- if (n > 0) {
- ofono_gprs_context_set_ipv4_address(gc, ip_addr[0], TRUE);
- if (n > 1) {
- ofono_gprs_context_set_ipv4_netmask(gc, ip_addr[1]);
- }
- }
+ return NULL;
}
-static void ril_gprs_context_set_ipv6(struct ofono_gprs_context *gc,
- char * const *ipv6_addr)
+static int ril_gprs_context_address_family(const char *addr)
{
- const guint n = gutil_strv_length(ipv6_addr);
-
- if (n > 0) {
- ofono_gprs_context_set_ipv6_address(gc, ipv6_addr[0]);
- if (n > 1) {
- const int p = atoi(ipv6_addr[1]);
- if (p > 0 && p <= 128) {
- ofono_gprs_context_set_ipv6_prefix_length(gc, p);
- }
- }
+ if (strchr(addr, ':')) {
+ return AF_INET6;
+ } else if (strchr(addr, '.')) {
+ return AF_INET;
+ } else {
+ return AF_UNSPEC;
}
}
@@ -111,9 +90,9 @@
ril_data_call_free(gcd->active_call);
gcd->active_call = NULL;
}
- if (gcd->calls_changed_event_id) {
- ril_data_remove_handler(gcd->data, gcd->calls_changed_event_id);
- gcd->calls_changed_event_id = 0;
+ if (gcd->calls_changed_id) {
+ ril_data_remove_handler(gcd->data, gcd->calls_changed_id);
+ gcd->calls_changed_id = 0;
}
if (gcd->mtu_watch) {
ril_mtu_watch_free(gcd->mtu_watch);
@@ -174,97 +153,161 @@
}
}
-static void ril_gprs_split_ip_by_protocol(char **ip_array,
- char ***split_ip_addr,
- char ***split_ipv6_addr)
+static void ril_gprs_context_set_address(struct ofono_gprs_context *gc,
+ const struct ril_data_call *call)
{
- const int n = gutil_strv_length(ip_array);
+ const char *ip_addr = NULL;
+ char *ip_mask = NULL;
+ const char *ipv6_addr = NULL;
+ unsigned char ipv6_prefix_length = 0;
+ char *tmp_ip_addr = NULL;
+ char *tmp_ipv6_addr = NULL;
+ char * const *list = call->addresses;
+ const int n = gutil_strv_length(list);
int i;
- *split_ipv6_addr = *split_ip_addr = NULL;
- for (i = 0; i < n && (!*split_ipv6_addr || !*split_ip_addr); i++) {
- const char *addr = ip_array[i];
- switch (ril_address_family(addr)) {
+ for (i = 0; i < n && (!ipv6_addr || !ip_addr); i++) {
+ const char *addr = list[i];
+ switch (ril_gprs_context_address_family(addr)) {
case AF_INET:
- if (!*split_ip_addr) {
- char *mask = ril_gprs_context_netmask(addr);
- *split_ip_addr = g_strsplit(addr, "/", 2);
- if (gutil_strv_length(*split_ip_addr) == 2) {
- g_free((*split_ip_addr)[1]);
- (*split_ip_addr)[1] = mask;
+ if (!ip_addr) {
+ const char* s = strstr(addr, "/");
+ if (s) {
+ const gsize len = s - addr;
+ tmp_ip_addr = g_strndup(addr, len);
+ ip_addr = tmp_ip_addr;
+ ip_mask = ril_gprs_context_netmask(s+1);
} else {
- /* This is rather unlikely to happen */
- *split_ip_addr =
- gutil_strv_add(*split_ip_addr,
- mask);
- g_free(mask);
+ ip_addr = addr;
+ }
+ if (!ip_mask) {
+ ip_mask = g_strdup("255.255.255.0");
}
}
break;
case AF_INET6:
- if (!*split_ipv6_addr) {
- *split_ipv6_addr = g_strsplit(addr, "/", 2);
+ if (!ipv6_addr) {
+ const char* s = strstr(addr, "/");
+ if (s) {
+ const gsize len = s - addr;
+ const int prefix = atoi(s + 1);
+ tmp_ipv6_addr = g_strndup(addr, len);
+ ipv6_addr = tmp_ipv6_addr;
+ if (prefix >= 0 && prefix <= 128) {
+ ipv6_prefix_length = prefix;
+ }
+ } else {
+ ipv6_addr = addr;
+ }
}
}
}
+
+ ofono_gprs_context_set_ipv4_address(gc, ip_addr, TRUE);
+ ofono_gprs_context_set_ipv4_netmask(gc, ip_mask);
+ ofono_gprs_context_set_ipv6_address(gc, ipv6_addr);
+ ofono_gprs_context_set_ipv6_prefix_length(gc, ipv6_prefix_length);
+
+ if (!ip_addr && !ipv6_addr) {
+ ofono_error("GPRS context: No IP address");
+ }
+
+ /* Allocate temporary strings */
+ g_free(ip_mask);
+ g_free(tmp_ip_addr);
+ g_free(tmp_ipv6_addr);
}
-static void ril_gprs_split_gw_by_protocol(char **gw_array, char **ip_gw,
- char **ipv6_gw)
+static void ril_gprs_context_set_gateway(struct ofono_gprs_context *gc,
+ const struct ril_data_call *call)
{
- const int n = gutil_strv_length(gw_array);
+ const char *ip_gw = NULL;
+ const char *ipv6_gw = NULL;
+ char * const *list = call->gateways;
+ const int n = gutil_strv_length(list);
int i;
- *ip_gw = *ipv6_gw = NULL;
- for (i = 0; i < n && (!*ipv6_gw || !*ip_gw); i++) {
- const char *gw_addr = gw_array[i];
- switch (ril_address_family(gw_addr)) {
|