3 * oFono - Open Source Telephony
5 * Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 #include <sys/ioctl.h>
32 #include <sys/socket.h>
34 #include <net/route.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
49 #define GPRS_FLAG_ATTACHING 0x1
50 #define GPRS_FLAG_RECHECK 0x2
51 #define GPRS_FLAG_ATTACHED_UPDATE 0x4
53 #define SETTINGS_STORE "gprs"
54 #define SETTINGS_GROUP "Settings"
55 #define MAX_CONTEXT_NAME_LENGTH 127
56 #define MAX_MESSAGE_PROXY_LENGTH 255
57 #define MAX_MESSAGE_CENTER_LENGTH 255
58 #define MAX_CONTEXTS 256
59 #define SUSPEND_TIMEOUT 8
61 /* 27.007 Section 7.29 */
63 PACKET_BEARER_NONE = 0,
64 PACKET_BEARER_GPRS = 1,
65 PACKET_BEARER_EGPRS = 2,
66 PACKET_BEARER_UMTS = 3,
67 PACKET_BEARER_HSUPA = 4,
68 PACKET_BEARER_HSDPA = 5,
69 PACKET_BEARER_HSUPA_HSDPA = 6,
70 PACKET_BEARER_EPS = 7,
75 ofono_bool_t attached;
76 ofono_bool_t driver_attached;
77 ofono_bool_t roaming_allowed;
79 ofono_bool_t suspended;
83 guint suspend_timeout;
84 struct idmap *pid_map;
85 unsigned int last_context_id;
86 struct idmap *cid_map;
88 struct ofono_netreg *netreg;
89 unsigned int netreg_watch;
90 unsigned int status_watch;
94 GSList *context_drivers;
95 const struct ofono_gprs_driver *driver;
97 struct ofono_atom *atom;
98 unsigned int spn_watch;
101 struct ipv4_settings {
102 ofono_bool_t static_ip;
110 struct ipv6_settings {
112 unsigned char prefix_len;
117 struct context_settings {
119 struct ipv4_settings *ipv4;
120 struct ipv6_settings *ipv6;
123 struct ofono_gprs_context {
124 struct ofono_gprs *gprs;
125 enum ofono_gprs_context_type type;
127 const struct ofono_gprs_context_driver *driver;
129 struct context_settings *settings;
130 struct ofono_atom *atom;
135 enum ofono_gprs_context_type type;
136 char name[MAX_CONTEXT_NAME_LENGTH + 1];
137 char message_proxy[MAX_MESSAGE_PROXY_LENGTH + 1];
138 char message_center[MAX_MESSAGE_CENTER_LENGTH + 1];
144 DBusMessage *pending;
145 struct ofono_gprs_primary_context context;
146 struct ofono_gprs_context *context_driver;
147 struct ofono_gprs *gprs;
150 static void gprs_netreg_update(struct ofono_gprs *gprs);
151 static void gprs_deactivate_next(struct ofono_gprs *gprs);
153 static GSList *g_drivers = NULL;
154 static GSList *g_context_drivers = NULL;
156 const char *packet_bearer_to_string(int bearer)
159 case PACKET_BEARER_NONE:
161 case PACKET_BEARER_GPRS:
163 case PACKET_BEARER_EGPRS:
165 case PACKET_BEARER_UMTS:
167 case PACKET_BEARER_HSUPA:
169 case PACKET_BEARER_HSDPA:
171 case PACKET_BEARER_HSUPA_HSDPA:
173 case PACKET_BEARER_EPS:
179 static const char *gprs_context_default_name(enum ofono_gprs_context_type type)
182 case OFONO_GPRS_CONTEXT_TYPE_ANY:
184 case OFONO_GPRS_CONTEXT_TYPE_INTERNET:
186 case OFONO_GPRS_CONTEXT_TYPE_MMS:
188 case OFONO_GPRS_CONTEXT_TYPE_WAP:
190 case OFONO_GPRS_CONTEXT_TYPE_IMS:
197 static const char *gprs_context_type_to_string(
198 enum ofono_gprs_context_type type)
201 case OFONO_GPRS_CONTEXT_TYPE_ANY:
203 case OFONO_GPRS_CONTEXT_TYPE_INTERNET:
205 case OFONO_GPRS_CONTEXT_TYPE_MMS:
207 case OFONO_GPRS_CONTEXT_TYPE_WAP:
209 case OFONO_GPRS_CONTEXT_TYPE_IMS:
216 static gboolean gprs_context_string_to_type(const char *str,
217 enum ofono_gprs_context_type *out)
219 if (g_str_equal(str, "internet")) {
220 *out = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
222 } else if (g_str_equal(str, "wap")) {
223 *out = OFONO_GPRS_CONTEXT_TYPE_WAP;
225 } else if (g_str_equal(str, "mms")) {
226 *out = OFONO_GPRS_CONTEXT_TYPE_MMS;
228 } else if (g_str_equal(str, "ims")) {
229 *out = OFONO_GPRS_CONTEXT_TYPE_IMS;
236 static const char *gprs_proto_to_string(enum ofono_gprs_proto proto)
239 case OFONO_GPRS_PROTO_IP:
241 case OFONO_GPRS_PROTO_IPV6:
243 case OFONO_GPRS_PROTO_IPV4V6:
250 static gboolean gprs_proto_from_string(const char *str,
251 enum ofono_gprs_proto *proto)
253 if (g_str_equal(str, "ip")) {
254 *proto = OFONO_GPRS_PROTO_IP;
256 } else if (g_str_equal(str, "ipv6")) {
257 *proto = OFONO_GPRS_PROTO_IPV6;
259 } else if (g_str_equal(str, "dual")) {
260 *proto = OFONO_GPRS_PROTO_IPV4V6;
267 static unsigned int gprs_cid_alloc(struct ofono_gprs *gprs)
269 return idmap_alloc(gprs->cid_map);
272 static void gprs_cid_release(struct ofono_gprs *gprs, unsigned int id)
274 idmap_put(gprs->cid_map, id);
277 static gboolean assign_context(struct pri_context *ctx)
279 struct idmap *cidmap = ctx->gprs->cid_map;
285 ctx->context.cid = gprs_cid_alloc(ctx->gprs);
286 if (ctx->context.cid == 0)
289 for (l = ctx->gprs->context_drivers; l; l = l->next) {
290 struct ofono_gprs_context *gc = l->data;
292 if (gc->inuse == TRUE)
295 if (gc->driver == NULL)
298 if (gc->driver->activate_primary == NULL ||
299 gc->driver->deactivate_primary == NULL)
302 if (gc->type != OFONO_GPRS_CONTEXT_TYPE_ANY &&
303 gc->type != ctx->type)
306 ctx->context_driver = gc;
307 ctx->context_driver->inuse = TRUE;
309 if (ctx->context.proto == OFONO_GPRS_PROTO_IPV4V6 ||
310 ctx->context.proto == OFONO_GPRS_PROTO_IP)
311 gc->settings->ipv4 = g_new0(struct ipv4_settings, 1);
313 if (ctx->context.proto == OFONO_GPRS_PROTO_IPV4V6 ||
314 ctx->context.proto == OFONO_GPRS_PROTO_IPV6)
315 gc->settings->ipv6 = g_new0(struct ipv6_settings, 1);
323 static void release_context(struct pri_context *ctx)
325 if (ctx == NULL || ctx->gprs == NULL || ctx->context_driver == NULL)
328 gprs_cid_release(ctx->gprs, ctx->context.cid);
329 ctx->context.cid = 0;
330 ctx->context_driver->inuse = FALSE;
331 ctx->context_driver = NULL;
335 static struct pri_context *gprs_context_by_path(struct ofono_gprs *gprs,
336 const char *ctx_path)
340 for (l = gprs->contexts; l; l = l->next) {
341 struct pri_context *ctx = l->data;
343 if (g_str_equal(ctx_path, ctx->path))
350 static void context_settings_free(struct context_settings *settings)
352 if (settings->ipv4) {
353 g_free(settings->ipv4->ip);
354 g_free(settings->ipv4->netmask);
355 g_free(settings->ipv4->gateway);
356 g_strfreev(settings->ipv4->dns);
357 g_free(settings->ipv4->proxy);
359 g_free(settings->ipv4);
360 settings->ipv4 = NULL;
363 if (settings->ipv6) {
364 g_free(settings->ipv6->ip);
365 g_free(settings->ipv6->gateway);
366 g_strfreev(settings->ipv6->dns);
368 g_free(settings->ipv6);
369 settings->ipv6 = NULL;
372 g_free(settings->interface);
373 settings->interface = NULL;
376 static void context_settings_append_ipv4(struct context_settings *settings,
377 DBusMessageIter *iter)
379 DBusMessageIter variant;
380 DBusMessageIter array;
385 arraysig[0] = DBUS_TYPE_ARRAY;
386 arraysig[1] = typesig[0] = DBUS_DICT_ENTRY_BEGIN_CHAR;
387 arraysig[2] = typesig[1] = DBUS_TYPE_STRING;
388 arraysig[3] = typesig[2] = DBUS_TYPE_VARIANT;
389 arraysig[4] = typesig[3] = DBUS_DICT_ENTRY_END_CHAR;
390 arraysig[5] = typesig[4] = '\0';
392 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
395 dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
397 if (settings == NULL || settings->ipv4 == NULL)
400 ofono_dbus_dict_append(&array, "Interface",
401 DBUS_TYPE_STRING, &settings->interface);
403 /* If we have a Proxy, no other settings are relevant */
404 if (settings->ipv4->proxy) {
405 ofono_dbus_dict_append(&array, "Proxy", DBUS_TYPE_STRING,
406 &settings->ipv4->proxy);
410 if (settings->ipv4->static_ip == TRUE)
415 ofono_dbus_dict_append(&array, "Method", DBUS_TYPE_STRING, &method);
417 if (settings->ipv4->ip)
418 ofono_dbus_dict_append(&array, "Address", DBUS_TYPE_STRING,
419 &settings->ipv4->ip);
421 if (settings->ipv4->netmask)
422 ofono_dbus_dict_append(&array, "Netmask", DBUS_TYPE_STRING,
423 &settings->ipv4->netmask);
425 if (settings->ipv4->gateway)
426 ofono_dbus_dict_append(&array, "Gateway", DBUS_TYPE_STRING,
427 &settings->ipv4->gateway);
429 if (settings->ipv4->dns)
430 ofono_dbus_dict_append_array(&array, "DomainNameServers",
432 &settings->ipv4->dns);
435 dbus_message_iter_close_container(&variant, &array);
437 dbus_message_iter_close_container(iter, &variant);
440 static void context_settings_append_ipv4_dict(struct context_settings *settings,
441 DBusMessageIter *dict)
443 DBusMessageIter entry;
444 const char *key = "Settings";
446 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
449 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
451 context_settings_append_ipv4(settings, &entry);
453 dbus_message_iter_close_container(dict, &entry);
456 static void context_settings_append_ipv6(struct context_settings *settings,
457 DBusMessageIter *iter)
459 DBusMessageIter variant;
460 DBusMessageIter array;
464 arraysig[0] = DBUS_TYPE_ARRAY;
465 arraysig[1] = typesig[0] = DBUS_DICT_ENTRY_BEGIN_CHAR;
466 arraysig[2] = typesig[1] = DBUS_TYPE_STRING;
467 arraysig[3] = typesig[2] = DBUS_TYPE_VARIANT;
468 arraysig[4] = typesig[3] = DBUS_DICT_ENTRY_END_CHAR;
469 arraysig[5] = typesig[4] = '\0';
471 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
474 dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
476 if (settings == NULL || settings->ipv6 == NULL)
479 ofono_dbus_dict_append(&array, "Interface",
480 DBUS_TYPE_STRING, &settings->interface);
482 if (settings->ipv6->ip)
483 ofono_dbus_dict_append(&array, "Address", DBUS_TYPE_STRING,
484 &settings->ipv6->ip);
486 if (settings->ipv6->prefix_len)
487 ofono_dbus_dict_append(&array, "PrefixLength", DBUS_TYPE_BYTE,
488 &settings->ipv6->prefix_len);
490 if (settings->ipv6->gateway)
491 ofono_dbus_dict_append(&array, "Gateway", DBUS_TYPE_STRING,
492 &settings->ipv6->gateway);
494 if (settings->ipv6->dns)
495 ofono_dbus_dict_append_array(&array, "DomainNameServers",
497 &settings->ipv6->dns);
500 dbus_message_iter_close_container(&variant, &array);
502 dbus_message_iter_close_container(iter, &variant);
505 static void context_settings_append_ipv6_dict(struct context_settings *settings,
506 DBusMessageIter *dict)
508 DBusMessageIter entry;
509 const char *key = "IPv6.Settings";
511 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
514 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
516 context_settings_append_ipv6(settings, &entry);
518 dbus_message_iter_close_container(dict, &entry);
521 static void signal_settings(struct pri_context *ctx, const char *prop,
522 void (*append)(struct context_settings *, DBusMessageIter *))
525 DBusConnection *conn = ofono_dbus_get_connection();
526 const char *path = ctx->path;
528 DBusMessageIter iter;
529 struct context_settings *settings;
531 signal = dbus_message_new_signal(path,
532 OFONO_CONNECTION_CONTEXT_INTERFACE,
538 dbus_message_iter_init_append(signal, &iter);
539 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &prop);
541 if (ctx->context_driver)
542 settings = ctx->context_driver->settings;
546 append(settings, &iter);
547 g_dbus_send_message(conn, signal);
550 static void pri_context_signal_settings(struct pri_context *ctx,
551 gboolean ipv4, gboolean ipv6)
554 signal_settings(ctx, "Settings",
555 context_settings_append_ipv4);
558 signal_settings(ctx, "IPv6.Settings",
559 context_settings_append_ipv6);
562 static void pri_parse_proxy(struct pri_context *ctx, const char *proxy)
564 char *scheme, *host, *port, *path;
566 scheme = g_strdup(proxy);
570 host = strstr(scheme, "://");
575 if (strcasecmp(scheme, "https") == 0)
576 ctx->proxy_port = 443;
577 else if (strcasecmp(scheme, "http") == 0)
578 ctx->proxy_port = 80;
585 ctx->proxy_port = 80;
588 path = strchr(host, '/');
592 port = strrchr(host, ':');
595 int tmp = strtol(port + 1, &end, 10);
599 ctx->proxy_port = tmp;
603 g_free(ctx->proxy_host);
604 ctx->proxy_host = g_strdup(host);
609 static void pri_ifupdown(const char *interface, ofono_bool_t active)
614 if (interface == NULL)
617 sk = socket(PF_INET, SOCK_DGRAM, 0);
621 memset(&ifr, 0, sizeof(ifr));
622 strncpy(ifr.ifr_name, interface, IFNAMSIZ);
624 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0)
627 if (active == TRUE) {
628 if (ifr.ifr_flags & IFF_UP)
630 ifr.ifr_flags |= IFF_UP;
632 if (!(ifr.ifr_flags & IFF_UP))
634 ifr.ifr_flags &= ~IFF_UP;
637 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
638 ofono_error("Failed to change interface flags");
644 static void pri_set_ipv4_addr(const char *interface, const char *address)
647 struct sockaddr_in addr;
650 if (interface == NULL)
653 sk = socket(PF_INET, SOCK_DGRAM, 0);
657 memset(&ifr, 0, sizeof(ifr));
658 strncpy(ifr.ifr_name, interface, IFNAMSIZ);
660 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0)
663 memset(&addr, 0, sizeof(addr));
664 addr.sin_family = AF_INET;
665 addr.sin_addr.s_addr = address ? inet_addr(address) : INADDR_ANY;
666 memcpy(&ifr.ifr_addr, &addr, sizeof(ifr.ifr_addr));
668 if (ioctl(sk, SIOCSIFADDR, &ifr) < 0) {
669 ofono_error("Failed to set interface address");
676 memset(&addr, 0, sizeof(addr));
677 addr.sin_family = AF_INET;
678 addr.sin_addr.s_addr = inet_addr("255.255.255.255");
679 memcpy(&ifr.ifr_netmask, &addr, sizeof(ifr.ifr_netmask));
681 if (ioctl(sk, SIOCSIFNETMASK, &ifr) < 0)
682 ofono_error("Failed to set interface netmask");
688 static void pri_setproxy(const char *interface, const char *proxy)
691 struct sockaddr_in addr;
694 if (interface == NULL)
697 sk = socket(PF_INET, SOCK_DGRAM, 0);
701 memset(&rt, 0, sizeof(rt));
702 rt.rt_flags = RTF_UP | RTF_HOST;
703 rt.rt_dev = (char *) interface;
705 memset(&addr, 0, sizeof(addr));
706 addr.sin_family = AF_INET;
707 addr.sin_addr.s_addr = inet_addr(proxy);
708 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
710 memset(&addr, 0, sizeof(addr));
711 addr.sin_family = AF_INET;
712 addr.sin_addr.s_addr = INADDR_ANY;
713 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
715 memset(&addr, 0, sizeof(addr));
716 addr.sin_family = AF_INET;
717 addr.sin_addr.s_addr = INADDR_ANY;
718 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
720 if (ioctl(sk, SIOCADDRT, &rt) < 0)
721 ofono_error("Failed to add proxy host route");
726 static void pri_reset_context_settings(struct pri_context *ctx)
728 struct context_settings *settings;
730 gboolean signal_ipv4;
731 gboolean signal_ipv6;
733 if (ctx->context_driver == NULL)
736 settings = ctx->context_driver->settings;
738 interface = settings->interface;
739 settings->interface = NULL;
741 signal_ipv4 = settings->ipv4 != NULL;
742 signal_ipv6 = settings->ipv6 != NULL;
744 context_settings_free(settings);
746 pri_context_signal_settings(ctx, signal_ipv4, signal_ipv6);
748 if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
749 pri_set_ipv4_addr(interface, NULL);
751 g_free(ctx->proxy_host);
752 ctx->proxy_host = NULL;
756 pri_ifupdown(interface, FALSE);
761 static void pri_update_mms_context_settings(struct pri_context *ctx)
763 struct ofono_gprs_context *gc = ctx->context_driver;
764 struct context_settings *settings = gc->settings;
766 if (ctx->message_proxy)
767 settings->ipv4->proxy = g_strdup(ctx->message_proxy);
769 pri_parse_proxy(ctx, ctx->message_proxy);
771 DBG("proxy %s port %u", ctx->proxy_host, ctx->proxy_port);
773 pri_set_ipv4_addr(settings->interface, settings->ipv4->ip);
776 pri_setproxy(settings->interface, ctx->proxy_host);
779 static void append_context_properties(struct pri_context *ctx,
780 DBusMessageIter *dict)
782 const char *type = gprs_context_type_to_string(ctx->type);
783 const char *proto = gprs_proto_to_string(ctx->context.proto);
784 const char *name = ctx->name;
786 const char *strvalue;
787 struct context_settings *settings;
789 ofono_dbus_dict_append(dict, "Name", DBUS_TYPE_STRING, &name);
792 ofono_dbus_dict_append(dict, "Active", DBUS_TYPE_BOOLEAN, &value);
794 ofono_dbus_dict_append(dict, "Type", DBUS_TYPE_STRING, &type);
796 ofono_dbus_dict_append(dict, "Protocol", DBUS_TYPE_STRING, &proto);
798 strvalue = ctx->context.apn;
799 ofono_dbus_dict_append(dict, "AccessPointName", DBUS_TYPE_STRING,
802 strvalue = ctx->context.username;
803 ofono_dbus_dict_append(dict, "Username", DBUS_TYPE_STRING,
806 strvalue = ctx->context.password;
807 ofono_dbus_dict_append(dict, "Password", DBUS_TYPE_STRING,
810 if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
811 strvalue = ctx->message_proxy;
812 ofono_dbus_dict_append(dict, "MessageProxy",
813 DBUS_TYPE_STRING, &strvalue);
815 strvalue = ctx->message_center;
816 ofono_dbus_dict_append(dict, "MessageCenter",
817 DBUS_TYPE_STRING, &strvalue);
820 if (ctx->context_driver)
821 settings = ctx->context_driver->settings;
825 context_settings_append_ipv4_dict(settings, dict);
826 context_settings_append_ipv6_dict(settings, dict);
829 static DBusMessage *pri_get_properties(DBusConnection *conn,
830 DBusMessage *msg, void *data)
832 struct pri_context *ctx = data;
834 DBusMessageIter iter;
835 DBusMessageIter dict;
837 reply = dbus_message_new_method_return(msg);
841 dbus_message_iter_init_append(reply, &iter);
843 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
844 OFONO_PROPERTIES_ARRAY_SIGNATURE,
846 append_context_properties(ctx, &dict);
847 dbus_message_iter_close_container(&iter, &dict);
852 static void pri_activate_callback(const struct ofono_error *error, void *data)
854 struct pri_context *ctx = data;
855 struct ofono_gprs_context *gc = ctx->context_driver;
856 DBusConnection *conn = ofono_dbus_get_connection();
861 if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
862 DBG("Activating context failed with error: %s",
863 telephony_error_to_str(error));
864 __ofono_dbus_pending_reply(&ctx->pending,
865 __ofono_error_failed(ctx->pending));
866 context_settings_free(ctx->context_driver->settings);
867 release_context(ctx);
872 __ofono_dbus_pending_reply(&ctx->pending,
873 dbus_message_new_method_return(ctx->pending));
875 if (gc->settings->interface != NULL) {
876 pri_ifupdown(gc->settings->interface, TRUE);
878 if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS &&
880 pri_update_mms_context_settings(ctx);
882 pri_context_signal_settings(ctx, gc->settings->ipv4 != NULL,
883 gc->settings->ipv6 != NULL);
887 ofono_dbus_signal_property_changed(conn, ctx->path,
888 OFONO_CONNECTION_CONTEXT_INTERFACE,
889 "Active", DBUS_TYPE_BOOLEAN, &value);
892 static void pri_deactivate_callback(const struct ofono_error *error, void *data)
894 struct pri_context *ctx = data;
895 DBusConnection *conn = ofono_dbus_get_connection();
898 if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
899 DBG("Deactivating context failed with error: %s",
900 telephony_error_to_str(error));
901 __ofono_dbus_pending_reply(&ctx->pending,
902 __ofono_error_failed(ctx->pending));
906 __ofono_dbus_pending_reply(&ctx->pending,
907 dbus_message_new_method_return(ctx->pending));
909 pri_reset_context_settings(ctx);
910 release_context(ctx);
913 ofono_dbus_signal_property_changed(conn, ctx->path,
914 OFONO_CONNECTION_CONTEXT_INTERFACE,
915 "Active", DBUS_TYPE_BOOLEAN, &value);
918 static DBusMessage *pri_set_apn(struct pri_context *ctx, DBusConnection *conn,
919 DBusMessage *msg, const char *apn)
921 GKeyFile *settings = ctx->gprs->settings;
923 if (strlen(apn) > OFONO_GPRS_MAX_APN_LENGTH)
924 return __ofono_error_invalid_format(msg);
926 if (g_str_equal(apn, ctx->context.apn))
927 return dbus_message_new_method_return(msg);
929 if (is_valid_apn(apn) == FALSE)
930 return __ofono_error_invalid_format(msg);
932 strcpy(ctx->context.apn, apn);
935 g_key_file_set_string(settings, ctx->key,
936 "AccessPointName", apn);
937 storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
940 g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
942 ofono_dbus_signal_property_changed(conn, ctx->path,
943 OFONO_CONNECTION_CONTEXT_INTERFACE,
945 DBUS_TYPE_STRING, &apn);
950 static DBusMessage *pri_set_username(struct pri_context *ctx,
951 DBusConnection *conn, DBusMessage *msg,
952 const char *username)
954 GKeyFile *settings = ctx->gprs->settings;
956 if (strlen(username) > OFONO_GPRS_MAX_USERNAME_LENGTH)
957 return __ofono_error_invalid_format(msg);
959 if (g_str_equal(username, ctx->context.username))
960 return dbus_message_new_method_return(msg);
962 strcpy(ctx->context.username, username);
965 g_key_file_set_string(settings, ctx->key,
966 "Username", username);
967 storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
970 g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
972 ofono_dbus_signal_property_changed(conn, ctx->path,
973 OFONO_CONNECTION_CONTEXT_INTERFACE,
975 DBUS_TYPE_STRING, &username);
980 static DBusMessage *pri_set_password(struct pri_context *ctx,
981 DBusConnection *conn, DBusMessage *msg,
982 const char *password)
984 GKeyFile *settings = ctx->gprs->settings;
986 if (strlen(password) > OFONO_GPRS_MAX_PASSWORD_LENGTH)
987 return __ofono_error_invalid_format(msg);
989 if (g_str_equal(password, ctx->context.password))
990 return dbus_message_new_method_return(msg);
992 strcpy(ctx->context.password, password);
995 g_key_file_set_string(settings, ctx->key,
996 "Password", password);
997 storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
1000 g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1002 ofono_dbus_signal_property_changed(conn, ctx->path,
1003 OFONO_CONNECTION_CONTEXT_INTERFACE,
1005 DBUS_TYPE_STRING, &password);
1010 static DBusMessage *pri_set_type(struct pri_context *ctx, DBusConnection *conn,
1011 DBusMessage *msg, const char *type)
1013 GKeyFile *settings = ctx->gprs->settings;
1014 enum ofono_gprs_context_type context_type;
1016 if (gprs_context_string_to_type(type, &context_type) == FALSE)
1017 return __ofono_error_invalid_format(msg);
1019 if (ctx->type == context_type)
1020 return dbus_message_new_method_return(msg);
1022 ctx->type = context_type;
1025 g_key_file_set_string(settings, ctx->key, "Type", type);
1026 storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
1029 g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1031 ofono_dbus_signal_property_changed(conn, ctx->path,
1032 OFONO_CONNECTION_CONTEXT_INTERFACE,
1033 "Type", DBUS_TYPE_STRING, &type);
1038 static DBusMessage *pri_set_proto(struct pri_context *ctx,
1039 DBusConnection *conn,
1040 DBusMessage *msg, const char *str)
1042 GKeyFile *settings = ctx->gprs->settings;
1043 enum ofono_gprs_proto proto;
1045 if (gprs_proto_from_string(str, &proto) == FALSE)
1046 return __ofono_error_invalid_format(msg);
1048 if (ctx->context.proto == proto)
1049 return dbus_message_new_method_return(msg);
1051 ctx->context.proto = proto;
1054 g_key_file_set_string(settings, ctx->key, "Protocol", str);
1055 storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
1058 g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1060 ofono_dbus_signal_property_changed(conn, ctx->path,
1061 OFONO_CONNECTION_CONTEXT_INTERFACE,
1062 "Protocol", DBUS_TYPE_STRING, &str);
1067 static DBusMessage *pri_set_name(struct pri_context *ctx, DBusConnection *conn,
1068 DBusMessage *msg, const char *name)
1070 GKeyFile *settings = ctx->gprs->settings;
1072 if (strlen(name) > MAX_CONTEXT_NAME_LENGTH)
1073 return __ofono_error_invalid_format(msg);
1075 if (ctx->name && g_str_equal(ctx->name, name))
1076 return dbus_message_new_method_return(msg);
1078 strcpy(ctx->name, name);
1081 g_key_file_set_string(settings, ctx->key, "Name", ctx->name);
1082 storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
1085 g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1087 ofono_dbus_signal_property_changed(conn, ctx->path,
1088 OFONO_CONNECTION_CONTEXT_INTERFACE,
1089 "Name", DBUS_TYPE_STRING, &name);
1094 static DBusMessage *pri_set_message_proxy(struct pri_context *ctx,
1095 DBusConnection *conn,
1096 DBusMessage *msg, const char *proxy)
1098 GKeyFile *settings = ctx->gprs->settings;
1100 if (strlen(proxy) > MAX_MESSAGE_PROXY_LENGTH)
1101 return __ofono_error_invalid_format(msg);
1103 if (ctx->message_proxy && g_str_equal(ctx->message_proxy, proxy))
1104 return dbus_message_new_method_return(msg);
1106 strcpy(ctx->message_proxy, proxy);
1109 g_key_file_set_string(settings, ctx->key, "MessageProxy",
1110 ctx->message_proxy);
1111 storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
1114 g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1116 ofono_dbus_signal_property_changed(conn, ctx->path,
1117 OFONO_CONNECTION_CONTEXT_INTERFACE,
1118 "MessageProxy", DBUS_TYPE_STRING, &proxy);
1123 static DBusMessage *pri_set_message_center(struct pri_context *ctx,
1124 DBusConnection *conn,
1125 DBusMessage *msg, const char *center)
1127 GKeyFile *settings = ctx->gprs->settings;
1129 if (strlen(center) > MAX_MESSAGE_CENTER_LENGTH)
1130 return __ofono_error_invalid_format(msg);
1132 if (ctx->message_center && g_str_equal(ctx->message_center, center))
1133 return dbus_message_new_method_return(msg);
1135 strcpy(ctx->message_center, center);
1138 g_key_file_set_string(settings, ctx->key, "MessageCenter",
1139 ctx->message_center);
1140 storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
1143 g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1145 ofono_dbus_signal_property_changed(conn, ctx->path,
1146 OFONO_CONNECTION_CONTEXT_INTERFACE,
1147 "MessageCenter", DBUS_TYPE_STRING, ¢er);
1152 static DBusMessage *pri_set_property(DBusConnection *conn,
1153 DBusMessage *msg, void *data)
1155 struct pri_context *ctx = data;
1156 DBusMessageIter iter;
1157 DBusMessageIter var;
1158 const char *property;
1162 if (!dbus_message_iter_init(msg, &iter))
1163 return __ofono_error_invalid_args(msg);
1165 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
1166 return __ofono_error_invalid_args(msg);
1168 dbus_message_iter_get_basic(&iter, &property);
1169 dbus_message_iter_next(&iter);
1171 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
1172 return __ofono_error_invalid_args(msg);
1174 dbus_message_iter_recurse(&iter, &var);
1176 if (g_str_equal(property, "Active")) {
1177 struct ofono_gprs_context *gc;
1179 if (ctx->gprs->pending)
1180 return __ofono_error_busy(msg);
1183 return __ofono_error_busy(msg);
1185 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_BOOLEAN)
1186 return __ofono_error_invalid_args(msg);
1188 dbus_message_iter_get_basic(&var, &value);
1190 if (ctx->active == (ofono_bool_t) value)
1191 return dbus_message_new_method_return(msg);
1193 if (value && !ctx->gprs->attached)
1194 return __ofono_error_not_attached(msg);
1196 if (ctx->gprs->flags & GPRS_FLAG_ATTACHING)
1197 return __ofono_error_attach_in_progress(msg);
1199 if (value && assign_context(ctx) == FALSE)
1200 return __ofono_error_not_implemented(msg);
1202 gc = ctx->context_driver;
1204 ctx->pending = dbus_message_ref(msg);
1207 gc->driver->activate_primary(gc, &ctx->context,
1208 pri_activate_callback, ctx);
1210 gc->driver->deactivate_primary(gc, ctx->context.cid,
1211 pri_deactivate_callback, ctx);
1216 /* All other properties are read-only when context is active */
1217 if (ctx->active == TRUE)
1218 return __ofono_error_in_use(msg);
1220 if (!strcmp(property, "AccessPointName")) {
1221 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
1222 return __ofono_error_invalid_args(msg);
1224 dbus_message_iter_get_basic(&var, &str);
1226 return pri_set_apn(ctx, conn, msg, str);
1227 } else if (!strcmp(property, "Type")) {
1228 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
1229 return __ofono_error_invalid_args(msg);
1231 dbus_message_iter_get_basic(&var, &str);
1233 return pri_set_type(ctx, conn, msg, str);
1234 } else if (!strcmp(property, "Protocol")) {
1235 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
1236 return __ofono_error_invalid_args(msg);
1238 dbus_message_iter_get_basic(&var, &str);
1240 return pri_set_proto(ctx, conn, msg, str);
1241 } else if (!strcmp(property, "Username")) {
1242 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
1243 return __ofono_error_invalid_args(msg);
1245 dbus_message_iter_get_basic(&var, &str);
1247 return pri_set_username(ctx, conn, msg, str);
1248 } else if (!strcmp(property, "Password")) {
1249 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
1250 return __ofono_error_invalid_args(msg);
1252 dbus_message_iter_get_basic(&var, &str);
1254 return pri_set_password(ctx, conn, msg, str);
1255 } else if (!strcmp(property, "Name")) {
1256 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
1257 return __ofono_error_invalid_args(msg);
1259 dbus_message_iter_get_basic(&var, &str);
1261 return pri_set_name(ctx, conn, msg, str);
1264 if (ctx->type != OFONO_GPRS_CONTEXT_TYPE_MMS)
1265 return __ofono_error_invalid_args(msg);
1267 if (!strcmp(property, "MessageProxy")) {
1268 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
1269 return __ofono_error_invalid_args(msg);
1271 dbus_message_iter_get_basic(&var, &str);
1273 return pri_set_message_proxy(ctx, conn, msg, str);
1274 } else if (!strcmp(property, "MessageCenter")) {
1275 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
1276 return __ofono_error_invalid_args(msg);
1278 dbus_message_iter_get_basic(&var, &str);
1280 return pri_set_message_center(ctx, conn, msg, str);
1283 return __ofono_error_invalid_args(msg);
1286 static const GDBusMethodTable context_methods[] = {
1287 { GDBUS_METHOD("GetProperties",
1288 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
1289 pri_get_properties) },
1290 { GDBUS_ASYNC_METHOD("SetProperty",
1291 GDBUS_ARGS({ "property", "s" }, { "value", "v" }),
1292 NULL, pri_set_property) },
1296 static const GDBusSignalTable context_signals[] = {
1297 { GDBUS_SIGNAL("PropertyChanged",
1298 GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
1302 static struct pri_context *pri_context_create(struct ofono_gprs *gprs,
1304 enum ofono_gprs_context_type type)
1306 struct pri_context *context = g_try_new0(struct pri_context, 1);
1308 if (context == NULL)
1312 name = gprs_context_default_name(type);
1319 context->gprs = gprs;
1320 strcpy(context->name, name);
1321 context->type = type;
1326 static void pri_context_destroy(gpointer userdata)
1328 struct pri_context *ctx = userdata;
1330 g_free(ctx->proxy_host);
1335 static gboolean context_dbus_register(struct pri_context *ctx)
1337 DBusConnection *conn = ofono_dbus_get_connection();
1339 const char *basepath;
1341 basepath = __ofono_atom_get_path(ctx->gprs->atom);
1343 snprintf(path, sizeof(path), "%s/context%u", basepath, ctx->id);
1345 if (!g_dbus_register_interface(conn, path,
1346 OFONO_CONNECTION_CONTEXT_INTERFACE,
1347 context_methods, context_signals,
1348 NULL, ctx, pri_context_destroy)) {
1349 ofono_error("Could not register PrimaryContext %s", path);
1350 idmap_put(ctx->gprs->pid_map, ctx->id);
1351 pri_context_destroy(ctx);
1356 ctx->path = g_strdup(path);
1357 ctx->key = ctx->path + strlen(basepath) + 1;
1362 static gboolean context_dbus_unregister(struct pri_context *ctx)
1364 DBusConnection *conn = ofono_dbus_get_connection();
1367 if (ctx->active == TRUE) {
1368 const char *interface =
1369 ctx->context_driver->settings->interface;
1371 if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS)
1372 pri_set_ipv4_addr(interface, NULL);
1374 pri_ifupdown(interface, FALSE);
1377 strcpy(path, ctx->path);
1378 idmap_put(ctx->gprs->pid_map, ctx->id);
1380 return g_dbus_unregister_interface(conn, path,
1381 OFONO_CONNECTION_CONTEXT_INTERFACE);
1384 static void update_suspended_property(struct ofono_gprs *gprs,
1385 ofono_bool_t suspended)
1387 DBusConnection *conn = ofono_dbus_get_connection();
1388 const char *path = __ofono_atom_get_path(gprs->atom);
1389 dbus_bool_t value = suspended;
1391 if (gprs->suspend_timeout) {
1392 g_source_remove(gprs->suspend_timeout);
1393 gprs->suspend_timeout = 0;
1396 if (gprs->suspended == suspended)
1399 DBG("%s GPRS service %s", __ofono_atom_get_path(gprs->atom),
1400 suspended ? "suspended" : "resumed");
1402 gprs->suspended = suspended;
1405 ofono_dbus_signal_property_changed(conn, path,
1406 OFONO_CONNECTION_MANAGER_INTERFACE,
1407 "Suspended", DBUS_TYPE_BOOLEAN, &value);
1410 static gboolean suspend_timeout(gpointer data)
1412 struct ofono_gprs *gprs = data;
1414 gprs->suspend_timeout = 0;
1415 update_suspended_property(gprs, TRUE);
1419 void ofono_gprs_suspend_notify(struct ofono_gprs *gprs, int cause)
1422 case GPRS_SUSPENDED_DETACHED:
1423 case GPRS_SUSPENDED_CALL:
1424 case GPRS_SUSPENDED_NO_COVERAGE:
1425 update_suspended_property(gprs, TRUE);
1428 case GPRS_SUSPENDED_SIGNALLING:
1429 case GPRS_SUSPENDED_UNKNOWN_CAUSE:
1430 if (gprs->suspend_timeout)
1431 g_source_remove(gprs->suspend_timeout);
1432 gprs->suspend_timeout = g_timeout_add_seconds(SUSPEND_TIMEOUT,
1439 void ofono_gprs_resume_notify(struct ofono_gprs *gprs)
1441 update_suspended_property(gprs, FALSE);
1444 static gboolean have_active_contexts(struct ofono_gprs *gprs)
1447 struct pri_context *ctx;
1449 for (l = gprs->contexts; l; l = l->next) {
1452 if (ctx->active == TRUE)
1459 static void release_active_contexts(struct ofono_gprs *gprs)
1462 struct pri_context *ctx;
1464 for (l = gprs->contexts; l; l = l->next) {
1465 struct ofono_gprs_context *gc;
1469 if (ctx->active == FALSE)
1472 /* This context is already being messed with */
1476 gc = ctx->context_driver;
1478 if (gc->driver->detach_shutdown != NULL)
1479 gc->driver->detach_shutdown(gc, ctx->context.cid);
1483 static void gprs_attached_update(struct ofono_gprs *gprs)
1485 DBusConnection *conn = ofono_dbus_get_connection();
1487 ofono_bool_t attached;
1490 attached = gprs->driver_attached &&
1491 (gprs->status == NETWORK_REGISTRATION_STATUS_REGISTERED ||
1492 gprs->status == NETWORK_REGISTRATION_STATUS_ROAMING);
1494 if (attached == gprs->attached)
1498 * If an active context is found, a PPP session might be still active
1499 * at driver level. "Attached" = TRUE property can't be signalled to
1500 * the applications registered on GPRS properties.
1501 * Active contexts have to be release at driver level.
1503 if (attached == FALSE) {
1504 release_active_contexts(gprs);
1506 } else if (have_active_contexts(gprs) == TRUE) {
1507 gprs->flags |= GPRS_FLAG_ATTACHED_UPDATE;
1511 gprs->attached = attached;
1513 path = __ofono_atom_get_path(gprs->atom);
1515 ofono_dbus_signal_property_changed(conn, path,
1516 OFONO_CONNECTION_MANAGER_INTERFACE,
1517 "Attached", DBUS_TYPE_BOOLEAN, &value);
1520 static void registration_status_cb(const struct ofono_error *error,
1521 int status, void *data)
1523 struct ofono_gprs *gprs = data;
1525 DBG("%s error %d status %d", __ofono_atom_get_path(gprs->atom),
1526 error->type, status);
1528 gprs->flags &= ~GPRS_FLAG_ATTACHING;
1530 if (error->type == OFONO_ERROR_TYPE_NO_ERROR)
1531 ofono_gprs_status_notify(gprs, status);
1533 gprs_attached_update(gprs);
1535 if (gprs->flags & GPRS_FLAG_RECHECK) {
1536 gprs->flags &= ~GPRS_FLAG_RECHECK;
1537 gprs_netreg_update(gprs);
1541 static void gprs_attach_callback(const struct ofono_error *error, void *data)
1543 struct ofono_gprs *gprs = data;
1545 DBG("%s error = %d", __ofono_atom_get_path(gprs->atom), error->type);
1547 if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
1548 gprs->driver_attached = !gprs->driver_attached;
1550 if (gprs->driver->attached_status == NULL) {
1551 struct ofono_error status_error;
1553 status_error.type = OFONO_ERROR_TYPE_FAILURE;
1554 status_error.error = 0;
1556 registration_status_cb(&status_error, -1, gprs);
1560 gprs->driver->attached_status(gprs, registration_status_cb, gprs);
1563 static void gprs_netreg_removed(struct ofono_gprs *gprs)
1565 gprs->netreg = NULL;
1567 gprs->flags &= ~(GPRS_FLAG_RECHECK | GPRS_FLAG_ATTACHING);
1568 gprs->status_watch = 0;
1569 gprs->netreg_status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;
1570 gprs->driver_attached = FALSE;
1572 gprs_attached_update(gprs);
1575 static void gprs_netreg_update(struct ofono_gprs *gprs)
1577 ofono_bool_t attach;
1579 attach = gprs->netreg_status == NETWORK_REGISTRATION_STATUS_REGISTERED;
1581 attach = attach || (gprs->roaming_allowed &&
1582 gprs->netreg_status == NETWORK_REGISTRATION_STATUS_ROAMING);
1584 attach = attach && gprs->powered;
1586 if (gprs->driver_attached == attach)
1589 if (gprs->flags & GPRS_FLAG_ATTACHING) {
1590 gprs->flags |= GPRS_FLAG_RECHECK;
1594 gprs->flags |= GPRS_FLAG_ATTACHING;
1596 gprs->driver->set_attached(gprs, attach, gprs_attach_callback, gprs);
1597 gprs->driver_attached = attach;
1600 static void netreg_status_changed(int status, int lac, int ci, int tech,
1601 const char *mcc, const char *mnc,
1604 struct ofono_gprs *gprs = data;
1608 if (gprs->netreg_status == status)
1611 gprs->netreg_status = status;
1613 gprs_netreg_update(gprs);
1616 static DBusMessage *gprs_get_properties(DBusConnection *conn,
1617 DBusMessage *msg, void *data)
1619 struct ofono_gprs *gprs = data;
1621 DBusMessageIter iter;
1622 DBusMessageIter dict;
1625 reply = dbus_message_new_method_return(msg);
1629 dbus_message_iter_init_append(reply, &iter);
1631 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1632 OFONO_PROPERTIES_ARRAY_SIGNATURE,
1635 value = gprs->attached;
1636 ofono_dbus_dict_append(&dict, "Attached", DBUS_TYPE_BOOLEAN, &value);
1638 if (gprs->bearer != -1) {
1639 const char *bearer = packet_bearer_to_string(gprs->bearer);
1641 ofono_dbus_dict_append(&dict, "Bearer",
1642 DBUS_TYPE_STRING, &bearer);
1645 value = gprs->roaming_allowed;
1646 ofono_dbus_dict_append(&dict, "RoamingAllowed",
1647 DBUS_TYPE_BOOLEAN, &value);
1649 value = gprs->powered;
1650 ofono_dbus_dict_append(&dict, "Powered", DBUS_TYPE_BOOLEAN, &value);
1652 if (gprs->attached) {
1653 value = gprs->suspended;
1654 ofono_dbus_dict_append(&dict, "Suspended",
1655 DBUS_TYPE_BOOLEAN, &value);
1658 dbus_message_iter_close_container(&iter, &dict);
1663 static DBusMessage *gprs_set_property(DBusConnection *conn,
1664 DBusMessage *msg, void *data)
1666 struct ofono_gprs *gprs = data;
1667 DBusMessageIter iter;
1668 DBusMessageIter var;
1669 const char *property;
1674 return __ofono_error_busy(msg);
1676 if (!dbus_message_iter_init(msg, &iter))
1677 return __ofono_error_invalid_args(msg);
1679 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
1680 return __ofono_error_invalid_args(msg);
1682 dbus_message_iter_get_basic(&iter, &property);
1683 dbus_message_iter_next(&iter);
1685 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
1686 return __ofono_error_invalid_args(msg);
1688 dbus_message_iter_recurse(&iter, &var);
1690 if (!strcmp(property, "RoamingAllowed")) {
1691 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_BOOLEAN)
1692 return __ofono_error_invalid_args(msg);
1694 dbus_message_iter_get_basic(&var, &value);
1696 if (gprs->roaming_allowed == (ofono_bool_t) value)
1697 return dbus_message_new_method_return(msg);
1699 gprs->roaming_allowed = value;
1701 if (gprs->settings) {
1702 g_key_file_set_integer(gprs->settings, SETTINGS_GROUP,
1704 gprs->roaming_allowed);
1705 storage_sync(gprs->imsi, SETTINGS_STORE,
1709 gprs_netreg_update(gprs);
1710 } else if (!strcmp(property, "Powered")) {
1711 if (gprs->driver->set_attached == NULL)
1712 return __ofono_error_not_implemented(msg);
1714 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_BOOLEAN)
1715 return __ofono_error_invalid_args(msg);
1717 dbus_message_iter_get_basic(&var, &value);
1719 if (gprs->powered == (ofono_bool_t) value)
1720 return dbus_message_new_method_return(msg);
1722 gprs->powered = value;
1724 if (gprs->settings) {
1725 g_key_file_set_integer(gprs->settings, SETTINGS_GROUP,
1726 "Powered", gprs->powered);
1727 storage_sync(gprs->imsi, SETTINGS_STORE,
1731 gprs_netreg_update(gprs);
1733 return __ofono_error_invalid_args(msg);
1736 path = __ofono_atom_get_path(gprs->atom);
1737 ofono_dbus_signal_property_changed(conn, path,
1738 OFONO_CONNECTION_MANAGER_INTERFACE,
1739 property, DBUS_TYPE_BOOLEAN, &value);
1741 return dbus_message_new_method_return(msg);
1744 static void write_context_settings(struct ofono_gprs *gprs,
1745 struct pri_context *context)
1747 g_key_file_set_string(gprs->settings, context->key,
1748 "Name", context->name);
1749 g_key_file_set_string(gprs->settings, context->key,
1750 "AccessPointName", context->context.apn);
1751 g_key_file_set_string(gprs->settings, context->key,
1752 "Username", context->context.username);
1753 g_key_file_set_string(gprs->settings, context->key,
1754 "Password", context->context.password);
1755 g_key_file_set_string(gprs->settings, context->key, "Type",
1756 gprs_context_type_to_string(context->type));
1757 g_key_file_set_string(gprs->settings, context->key, "Protocol",
1758 gprs_proto_to_string(context->context.proto));
1760 if (context->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
1761 g_key_file_set_string(gprs->settings, context->key,
1763 context->message_proxy);
1764 g_key_file_set_string(gprs->settings, context->key,
1766 context->message_center);
1770 static struct pri_context *add_context(struct ofono_gprs *gprs,
1772 enum ofono_gprs_context_type type)
1775 struct pri_context *context;
1777 if (gprs->last_context_id)
1778 id = idmap_alloc_next(gprs->pid_map, gprs->last_context_id);
1780 id = idmap_alloc(gprs->pid_map);
1782 if (id > idmap_get_max(gprs->pid_map))
1785 context = pri_context_create(gprs, name, type);
1786 if (context == NULL) {
1787 idmap_put(gprs->pid_map, id);
1788 ofono_error("Unable to allocate context struct");
1794 DBG("Registering new context");
1796 if (!context_dbus_register(context)) {
1797 ofono_error("Unable to register primary context");
1801 gprs->last_context_id = id;
1803 if (gprs->settings) {
1804 write_context_settings(gprs, context);
1805 storage_sync(gprs->imsi, SETTINGS_STORE, gprs->settings);
1808 gprs->contexts = g_slist_append(gprs->contexts, context);
1813 static DBusMessage *gprs_add_context(DBusConnection *conn,
1814 DBusMessage *msg, void *data)
1816 struct ofono_gprs *gprs = data;
1817 struct pri_context *context;
1818 const char *typestr;
1821 enum ofono_gprs_context_type type;
1822 DBusMessage *signal;
1824 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &typestr,
1826 return __ofono_error_invalid_args(msg);
1828 if (gprs_context_string_to_type(typestr, &type) == FALSE)
1829 return __ofono_error_invalid_format(msg);
1831 name = gprs_context_default_name(type);
1835 context = add_context(gprs, name, type);
1836 if (context == NULL)
1837 return __ofono_error_failed(msg);
1839 path = context->path;
1841 g_dbus_send_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &path,
1844 path = __ofono_atom_get_path(gprs->atom);
1845 signal = dbus_message_new_signal(path,
1846 OFONO_CONNECTION_MANAGER_INTERFACE,
1850 DBusMessageIter iter;
1851 DBusMessageIter dict;
1853 dbus_message_iter_init_append(signal, &iter);
1855 path = context->path;
1856 dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1859 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1860 OFONO_PROPERTIES_ARRAY_SIGNATURE,
1862 append_context_properties(context, &dict);
1863 dbus_message_iter_close_container(&iter, &dict);
1865 g_dbus_send_message(conn, signal);
1871 static void gprs_deactivate_for_remove(const struct ofono_error *error,
1874 struct pri_context *ctx = data;
1875 struct ofono_gprs *gprs = ctx->gprs;
1876 DBusConnection *conn = ofono_dbus_get_connection();
1878 const char *atompath;
1881 if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
1882 DBG("Removing context failed with error: %s",
1883 telephony_error_to_str(error));
1885 __ofono_dbus_pending_reply(&gprs->pending,
1886 __ofono_error_failed(gprs->pending));
1890 pri_reset_context_settings(ctx);
1891 release_context(ctx);
1894 ofono_dbus_signal_property_changed(conn, ctx->path,
1895 OFONO_CONNECTION_CONTEXT_INTERFACE,
1896 "Active", DBUS_TYPE_BOOLEAN, &value);
1898 if (gprs->settings) {
1899 g_key_file_remove_group(gprs->settings, ctx->key, NULL);
1900 storage_sync(gprs->imsi, SETTINGS_STORE, gprs->settings);
1903 /* Make a backup copy of path for signal emission below */
1904 path = g_strdup(ctx->path);
1906 context_dbus_unregister(ctx);
1907 gprs->contexts = g_slist_remove(gprs->contexts, ctx);
1909 __ofono_dbus_pending_reply(&gprs->pending,
1910 dbus_message_new_method_return(gprs->pending));
1912 atompath = __ofono_atom_get_path(gprs->atom);
1913 g_dbus_emit_signal(conn, atompath, OFONO_CONNECTION_MANAGER_INTERFACE,
1914 "ContextRemoved", DBUS_TYPE_OBJECT_PATH, &path,
1919 static DBusMessage *gprs_remove_context(DBusConnection *conn,
1920 DBusMessage *msg, void *data)
1922 struct ofono_gprs *gprs = data;
1923 struct pri_context *ctx;
1925 const char *atompath;
1928 return __ofono_error_busy(msg);
1930 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
1932 return __ofono_error_invalid_args(msg);
1934 if (path[0] == '\0')
1935 return __ofono_error_invalid_format(msg);
1937 ctx = gprs_context_by_path(gprs, path);
1939 return __ofono_error_not_found(msg);
1942 struct ofono_gprs_context *gc = ctx->context_driver;
1944 /* This context is already being messed with */
1946 return __ofono_error_busy(msg);
1948 gprs->pending = dbus_message_ref(msg);
1949 gc->driver->deactivate_primary(gc, ctx->context.cid,
1950 gprs_deactivate_for_remove, ctx);
1954 if (gprs->settings) {
1955 g_key_file_remove_group(gprs->settings, ctx->key, NULL);
1956 storage_sync(gprs->imsi, SETTINGS_STORE, gprs->settings);
1959 DBG("Unregistering context: %s", ctx->path);
1960 context_dbus_unregister(ctx);
1961 gprs->contexts = g_slist_remove(gprs->contexts, ctx);
1963 g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1965 atompath = __ofono_atom_get_path(gprs->atom);
1966 g_dbus_emit_signal(conn, atompath, OFONO_CONNECTION_MANAGER_INTERFACE,
1967 "ContextRemoved", DBUS_TYPE_OBJECT_PATH, &path,
1973 static void gprs_deactivate_for_all(const struct ofono_error *error,
1976 struct pri_context *ctx = data;
1977 struct ofono_gprs *gprs = ctx->gprs;
1978 DBusConnection *conn;
1981 if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
1982 __ofono_dbus_pending_reply(&gprs->pending,
1983 __ofono_error_failed(gprs->pending));
1987 pri_reset_context_settings(ctx);
1988 release_context(ctx);
1990 value = ctx->active;
1991 conn = ofono_dbus_get_connection();
1992 ofono_dbus_signal_property_changed(conn, ctx->path,
1993 OFONO_CONNECTION_CONTEXT_INTERFACE,
1994 "Active", DBUS_TYPE_BOOLEAN, &value);
1996 gprs_deactivate_next(gprs);
1999 static void gprs_deactivate_next(struct ofono_gprs *gprs)
2002 struct pri_context *ctx;
2003 struct ofono_gprs_context *gc;
2005 for (l = gprs->contexts; l; l = l->next) {
2008 if (ctx->active == FALSE)
2011 gc = ctx->context_driver;
2012 gc->driver->deactivate_primary(gc, ctx->context.cid,
2013 gprs_deactivate_for_all, ctx);
2018 __ofono_dbus_pending_reply(&gprs->pending,
2019 dbus_message_new_method_return(gprs->pending));
2022 static DBusMessage *gprs_deactivate_all(DBusConnection *conn,
2023 DBusMessage *msg, void *data)
2025 struct ofono_gprs *gprs = data;
2027 struct pri_context *ctx;
2030 return __ofono_error_busy(msg);
2032 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INVALID))
2033 return __ofono_error_invalid_args(msg);
2035 for (l = gprs->contexts; l; l = l->next) {
2039 return __ofono_error_busy(msg);
2042 gprs->pending = dbus_message_ref(msg);
2044 gprs_deactivate_next(gprs);
2049 static DBusMessage *gprs_get_contexts(DBusConnection *conn,
2050 DBusMessage *msg, void *data)
2052 struct ofono_gprs *gprs = data;
2054 DBusMessageIter iter;
2055 DBusMessageIter array;
2056 DBusMessageIter entry, dict;
2059 struct pri_context *ctx;
2061 reply = dbus_message_new_method_return(msg);
2065 dbus_message_iter_init_append(reply, &iter);
2067 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
2068 DBUS_STRUCT_BEGIN_CHAR_AS_STRING
2069 DBUS_TYPE_OBJECT_PATH_AS_STRING
2070 DBUS_TYPE_ARRAY_AS_STRING
2071 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
2072 DBUS_TYPE_STRING_AS_STRING
2073 DBUS_TYPE_VARIANT_AS_STRING
2074 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
2075 DBUS_STRUCT_END_CHAR_AS_STRING,
2078 for (l = gprs->contexts; l; l = l->next) {
2083 dbus_message_iter_open_container(&array, DBUS_TYPE_STRUCT,
2085 dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
2087 dbus_message_iter_open_container(&entry, DBUS_TYPE_ARRAY,
2088 OFONO_PROPERTIES_ARRAY_SIGNATURE,
2091 append_context_properties(ctx, &dict);
2092 dbus_message_iter_close_container(&entry, &dict);
2093 dbus_message_iter_close_container(&array, &entry);
2096 dbus_message_iter_close_container(&iter, &array);
2101 static const GDBusMethodTable manager_methods[] = {
2102 { GDBUS_METHOD("GetProperties",
2103 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
2104 gprs_get_properties) },
2105 { GDBUS_METHOD("SetProperty",
2106 GDBUS_ARGS({ "property", "s" }, { "value", "v" }),
2107 NULL, gprs_set_property) },
2108 { GDBUS_ASYNC_METHOD("AddContext",
2109 GDBUS_ARGS({ "type", "s" }),
2110 GDBUS_ARGS({ "path", "o" }),
2111 gprs_add_context) },
2112 { GDBUS_ASYNC_METHOD("RemoveContext",
2113 GDBUS_ARGS({ "path", "o" }), NULL,
2114 gprs_remove_context) },
2115 { GDBUS_ASYNC_METHOD("DeactivateAll", NULL, NULL,
2116 gprs_deactivate_all) },
2117 { GDBUS_METHOD("GetContexts", NULL,
2118 GDBUS_ARGS({ "contexts_with_properties", "a(oa{sv})" }),
2119 gprs_get_contexts) },
2123 static const GDBusSignalTable manager_signals[] = {
2124 { GDBUS_SIGNAL("PropertyChanged",
2125 GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
2126 { GDBUS_SIGNAL("ContextAdded",
2127 GDBUS_ARGS({ "path", "o" }, { "properties", "v" })) },
2128 { GDBUS_SIGNAL("ContextRemoved", GDBUS_ARGS({ "path", "o" })) },
2132 void ofono_gprs_detached_notify(struct ofono_gprs *gprs)
2134 DBG("%s", __ofono_atom_get_path(gprs->atom));
2136 gprs->driver_attached = FALSE;
2137 gprs_attached_update(gprs);
2140 * TODO: The network forced a detach, we should wait for some time
2141 * and try to re-attach. This might also be related to a suspend
2142 * event while voicecall is active.
2146 void ofono_gprs_status_notify(struct ofono_gprs *gprs, int status)
2148 DBG("%s status %d", __ofono_atom_get_path(gprs->atom), status);
2150 gprs->status = status;
2152 if (status != NETWORK_REGISTRATION_STATUS_REGISTERED &&
2153 status != NETWORK_REGISTRATION_STATUS_ROAMING) {
2154 gprs_attached_update(gprs);
2159 * If we're already taking action, e.g. attaching or detaching, then
2160 * ignore this notification for now, we will take appropriate action
2161 * after the set_attach operation has completed
2163 if (gprs->flags & GPRS_FLAG_ATTACHING)
2166 /* We registered without being powered */
2167 if (gprs->powered == FALSE)
2170 if (gprs->roaming_allowed == FALSE &&
2171 status == NETWORK_REGISTRATION_STATUS_ROAMING)
2174 gprs->driver_attached = TRUE;
2175 gprs_attached_update(gprs);
2180 gprs->flags |= GPRS_FLAG_ATTACHING;
2181 gprs->driver->set_attached(gprs, FALSE, gprs_attach_callback, gprs);
2184 void ofono_gprs_set_cid_range(struct ofono_gprs *gprs,
2185 unsigned int min, unsigned int max)
2191 idmap_free(gprs->cid_map);
2193 gprs->cid_map = idmap_new_from_range(min, max);
2196 static void gprs_context_unregister(struct ofono_atom *atom)
2198 struct ofono_gprs_context *gc = __ofono_atom_get_data(atom);
2199 DBusConnection *conn = ofono_dbus_get_connection();
2201 struct pri_context *ctx;
2204 DBG("%p, %p", gc, gc->gprs);
2206 if (gc->gprs == NULL)
2209 for (l = gc->gprs->contexts; l; l = l->next) {
2212 if (ctx->context_driver != gc)
2215 if (ctx->pending != NULL)
2216 __ofono_dbus_pending_reply(&ctx->pending,
2217 __ofono_error_failed(ctx->pending));
2219 if (ctx->active == FALSE)
2222 pri_reset_context_settings(ctx);
2223 release_context(ctx);
2226 ofono_dbus_signal_property_changed(conn, ctx->path,
2227 OFONO_CONNECTION_CONTEXT_INTERFACE,
2228 "Active", DBUS_TYPE_BOOLEAN, &value);
2231 gc->gprs->context_drivers = g_slist_remove(gc->gprs->context_drivers,
2237 context_settings_free(gc->settings);
2238 g_free(gc->settings);
2239 gc->settings = NULL;
2243 void ofono_gprs_add_context(struct ofono_gprs *gprs,
2244 struct ofono_gprs_context *gc)
2246 if (gc->driver == NULL)
2250 gc->settings = g_new0(struct context_settings, 1);
2252 gprs->context_drivers = g_slist_append(gprs->context_drivers, gc);
2253 __ofono_atom_register(gc->atom, gprs_context_unregister);
2256 void ofono_gprs_bearer_notify(struct ofono_gprs *gprs, int bearer)
2258 DBusConnection *conn = ofono_dbus_get_connection();
2262 if (gprs->bearer == bearer)
2265 gprs->bearer = bearer;
2266 path = __ofono_atom_get_path(gprs->atom);
2267 value = packet_bearer_to_string(bearer);
2268 ofono_dbus_signal_property_changed(conn, path,
2269 OFONO_CONNECTION_CONTEXT_INTERFACE,
2270 "Bearer", DBUS_TYPE_STRING, &value);
2273 void ofono_gprs_context_deactivated(struct ofono_gprs_context *gc,
2276 DBusConnection *conn = ofono_dbus_get_connection();
2278 struct pri_context *ctx;
2281 if (gc->gprs == NULL)
2284 for (l = gc->gprs->contexts; l; l = l->next) {
2287 if (ctx->context.cid != cid)
2290 if (ctx->active == FALSE)
2293 pri_reset_context_settings(ctx);
2294 release_context(ctx);
2297 ofono_dbus_signal_property_changed(conn, ctx->path,
2298 OFONO_CONNECTION_CONTEXT_INTERFACE,
2299 "Active", DBUS_TYPE_BOOLEAN, &value);
2303 * If "Attached" property was about to be signalled as TRUE but there
2304 * were still active contexts, try again to signal "Attached" property
2305 * to registered applications after active contexts have been released.
2307 if (gc->gprs->flags & GPRS_FLAG_ATTACHED_UPDATE) {
2308 gc->gprs->flags &= ~GPRS_FLAG_ATTACHED_UPDATE;
2309 gprs_attached_update(gc->gprs);
2313 int ofono_gprs_context_driver_register(
2314 const struct ofono_gprs_context_driver *d)
2316 DBG("driver: %p, name: %s", d, d->name);
2318 if (d->probe == NULL)
2321 g_context_drivers = g_slist_prepend(g_context_drivers, (void *) d);
2326 void ofono_gprs_context_driver_unregister(
2327 const struct ofono_gprs_context_driver *d)
2329 DBG("driver: %p, name: %s", d, d->name);
2331 g_context_drivers = g_slist_remove(g_context_drivers, (void *) d);
2334 static void gprs_context_remove(struct ofono_atom *atom)
2336 struct ofono_gprs_context *gc = __ofono_atom_get_data(atom);
2338 DBG("atom: %p", atom);
2343 if (gc->driver && gc->driver->remove)
2344 gc->driver->remove(gc);
2349 struct ofono_gprs_context *ofono_gprs_context_create(struct ofono_modem *modem,
2350 unsigned int vendor,
2351 const char *driver, void *data)
2353 struct ofono_gprs_context *gc;
2359 gc = g_try_new0(struct ofono_gprs_context, 1);
2363 gc->type = OFONO_GPRS_CONTEXT_TYPE_ANY;
2365 gc->atom = __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_GPRS_CONTEXT,
2366 gprs_context_remove, gc);
2368 for (l = g_context_drivers; l; l = l->next) {
2369 const struct ofono_gprs_context_driver *drv = l->data;
2371 if (g_strcmp0(drv->name, driver))
2374 if (drv->probe(gc, vendor, data) < 0)
2384 void ofono_gprs_context_remove(struct ofono_gprs_context *gc)
2389 __ofono_atom_free(gc->atom);
2392 void ofono_gprs_context_set_data(struct ofono_gprs_context *gc, void *data)
2394 gc->driver_data = data;
2397 void *ofono_gprs_context_get_data(struct ofono_gprs_context *gc)
2399 return gc->driver_data;
2402 struct ofono_modem *ofono_gprs_context_get_modem(struct ofono_gprs_context *gc)
2404 return __ofono_atom_get_modem(gc->atom);
2407 void ofono_gprs_context_set_type(struct ofono_gprs_context *gc,
2408 enum ofono_gprs_context_type type)
2410 DBG("type %d", type);
2415 void ofono_gprs_context_set_interface(struct ofono_gprs_context *gc,
2416 const char *interface)
2418 struct context_settings *settings = gc->settings;
2420 g_free(settings->interface);
2421 settings->interface = g_strdup(interface);
2424 void ofono_gprs_context_set_ipv4_address(struct ofono_gprs_context *gc,
2425 const char *address,
2426 ofono_bool_t static_ip)
2428 struct context_settings *settings = gc->settings;
2430 if (settings->ipv4 == NULL)
2433 g_free(settings->ipv4->ip);
2434 settings->ipv4->ip = g_strdup(address);
2435 settings->ipv4->static_ip = static_ip;
2438 void ofono_gprs_context_set_ipv4_netmask(struct ofono_gprs_context *gc,
2439 const char *netmask)
2441 struct context_settings *settings = gc->settings;
2443 if (settings->ipv4 == NULL)
2446 g_free(settings->ipv4->netmask);
2447 settings->ipv4->netmask = g_strdup(netmask);
2450 void ofono_gprs_context_set_ipv4_gateway(struct ofono_gprs_context *gc,
2451 const char *gateway)
2453 struct context_settings *settings = gc->settings;
2455 if (settings->ipv4 == NULL)
2458 g_free(settings->ipv4->gateway);
2459 settings->ipv4->gateway = g_strdup(gateway);
2462 void ofono_gprs_context_set_ipv4_dns_servers(struct ofono_gprs_context *gc,
2465 struct context_settings *settings = gc->settings;
2467 if (settings->ipv4 == NULL)
2470 g_strfreev(settings->ipv4->dns);
2471 settings->ipv4->dns = g_strdupv((char **) dns);
2474 void ofono_gprs_context_set_ipv6_address(struct ofono_gprs_context *gc,
2475 const char *address)
2477 struct context_settings *settings = gc->settings;
2479 if (settings->ipv6 == NULL)
2482 g_free(settings->ipv6->ip);
2483 settings->ipv6->ip = g_strdup(address);
2486 void ofono_gprs_context_set_ipv6_prefix_length(struct ofono_gprs_context *gc,
2487 unsigned char length)
2489 struct context_settings *settings = gc->settings;
2491 if (settings->ipv6 == NULL)
2494 settings->ipv6->prefix_len = length;
2497 void ofono_gprs_context_set_ipv6_gateway(struct ofono_gprs_context *gc,
2498 const char *gateway)
2500 struct context_settings *settings = gc->settings;
2502 if (settings->ipv6 == NULL)
2505 g_free(settings->ipv6->gateway);
2506 settings->ipv6->gateway = g_strdup(gateway);
2509 void ofono_gprs_context_set_ipv6_dns_servers(struct ofono_gprs_context *gc,
2512 struct context_settings *settings = gc->settings;
2514 if (settings->ipv6 == NULL)
2517 g_strfreev(settings->ipv6->dns);
2518 settings->ipv6->dns = g_strdupv((char **) dns);
2521 int ofono_gprs_driver_register(const struct ofono_gprs_driver *d)
2523 DBG("driver: %p, name: %s", d, d->name);
2525 if (d->probe == NULL)
2528 g_drivers = g_slist_prepend(g_drivers, (void *)d);
2533 void ofono_gprs_driver_unregister(const struct ofono_gprs_driver *d)
2535 DBG("driver: %p, name: %s", d, d->name);
2537 g_drivers = g_slist_remove(g_drivers, (void *)d);
2540 static void free_contexts(struct ofono_gprs *gprs)
2544 if (gprs->settings) {
2545 storage_close(gprs->imsi, SETTINGS_STORE,
2546 gprs->settings, TRUE);
2550 gprs->settings = NULL;
2553 for (l = gprs->contexts; l; l = l->next) {
2554 struct pri_context *context = l->data;
2556 context_dbus_unregister(context);
2559 g_slist_free(gprs->contexts);
2562 static void gprs_unregister(struct ofono_atom *atom)
2564 DBusConnection *conn = ofono_dbus_get_connection();
2565 struct ofono_gprs *gprs = __ofono_atom_get_data(atom);
2566 struct ofono_modem *modem = __ofono_atom_get_modem(atom);
2567 const char *path = __ofono_atom_get_path(atom);
2571 free_contexts(gprs);
2573 if (gprs->cid_map) {
2574 idmap_free(gprs->cid_map);
2575 gprs->cid_map = NULL;
2578 if (gprs->netreg_watch) {
2579 if (gprs->status_watch) {
2580 __ofono_netreg_remove_status_watch(gprs->netreg,
2581 gprs->status_watch);
2582 gprs->status_watch = 0;
2585 __ofono_modem_remove_atom_watch(modem, gprs->netreg_watch);
2586 gprs->netreg_watch = 0;
2587 gprs->netreg = NULL;
2590 if (gprs->spn_watch) {
2591 struct ofono_sim *sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM,
2594 ofono_sim_remove_spn_watch(sim, &gprs->spn_watch);
2597 ofono_modem_remove_interface(modem,
2598 OFONO_CONNECTION_MANAGER_INTERFACE);
2599 g_dbus_unregister_interface(conn, path,
2600 OFONO_CONNECTION_MANAGER_INTERFACE);
2603 static void gprs_remove(struct ofono_atom *atom)
2605 struct ofono_gprs *gprs = __ofono_atom_get_data(atom);
2608 DBG("atom: %p", atom);
2613 if (gprs->suspend_timeout)
2614 g_source_remove(gprs->suspend_timeout);
2616 if (gprs->pid_map) {
2617 idmap_free(gprs->pid_map);
2618 gprs->pid_map = NULL;
2621 for (l = gprs->context_drivers; l; l = l->next) {
2622 struct ofono_gprs_context *gc = l->data;
2627 g_slist_free(gprs->context_drivers);
2629 if (gprs->driver && gprs->driver->remove)
2630 gprs->driver->remove(gprs);
2635 struct ofono_gprs *ofono_gprs_create(struct ofono_modem *modem,
2636 unsigned int vendor,
2637 const char *driver, void *data)
2639 struct ofono_gprs *gprs;
2645 gprs = g_try_new0(struct ofono_gprs, 1);
2649 gprs->atom = __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_GPRS,
2652 for (l = g_drivers; l; l = l->next) {
2653 const struct ofono_gprs_driver *drv = l->data;
2655 if (g_strcmp0(drv->name, driver))
2658 if (drv->probe(gprs, vendor, data) < 0)
2665 gprs->status = NETWORK_REGISTRATION_STATUS_UNKNOWN;
2666 gprs->netreg_status = NETWORK_REGISTRATION_STATUS_UNKNOWN;
2667 gprs->pid_map = idmap_new(MAX_CONTEXTS);
2672 static void netreg_watch(struct ofono_atom *atom,
2673 enum ofono_atom_watch_condition cond,
2676 struct ofono_gprs *gprs = data;
2678 if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
2679 gprs_netreg_removed(gprs);
2683 gprs->netreg = __ofono_atom_get_data(atom);
2684 gprs->netreg_status = ofono_netreg_get_status(gprs->netreg);
2685 gprs->status_watch = __ofono_netreg_add_status_watch(gprs->netreg,
2686 netreg_status_changed, gprs, NULL);
2688 gprs_netreg_update(gprs);
2691 static gboolean load_context(struct ofono_gprs *gprs, const char *group)
2694 char *typestr = NULL;
2695 char *protostr = NULL;
2696 char *username = NULL;
2697 char *password = NULL;
2699 char *msgproxy = NULL;
2700 char *msgcenter = NULL;
2701 gboolean ret = FALSE;
2702 gboolean legacy = FALSE;
2703 struct pri_context *context;
2704 enum ofono_gprs_context_type type;
2705 enum ofono_gprs_proto proto;
2708 if (sscanf(group, "context%d", &id) != 1) {
2709 if (sscanf(group, "primarycontext%d", &id) != 1)
2715 if (id < 1 || id > MAX_CONTEXTS)
2718 name = g_key_file_get_string(gprs->settings, group, "Name", NULL);
2722 typestr = g_key_file_get_string(gprs->settings, group, "Type", NULL);
2723 if (typestr == NULL)
2726 if (gprs_context_string_to_type(typestr, &type) == FALSE)
2729 protostr = g_key_file_get_string(gprs->settings, group,
2731 if (protostr == NULL)
2732 protostr = g_strdup("ip");
2734 if (gprs_proto_from_string(protostr, &proto) == FALSE)
2737 username = g_key_file_get_string(gprs->settings, group,
2739 if (username == NULL)
2742 if (strlen(username) > OFONO_GPRS_MAX_USERNAME_LENGTH)
2745 password = g_key_file_get_string(gprs->settings, group,
2747 if (password == NULL)
2750 if (strlen(password) > OFONO_GPRS_MAX_PASSWORD_LENGTH)
2753 apn = g_key_file_get_string(gprs->settings, group,
2754 "AccessPointName", NULL);
2758 if (strlen(apn) > OFONO_GPRS_MAX_APN_LENGTH)
2761 if (type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
2762 msgproxy = g_key_file_get_string(gprs->settings, group,
2763 "MessageProxy", NULL);
2765 msgcenter = g_key_file_get_string(gprs->settings, group,
2766 "MessageCenter", NULL);
2770 * Accept empty (just created) APNs, but don't allow other
2773 if (apn[0] != '\0' && is_valid_apn(apn) == FALSE)
2776 context = pri_context_create(gprs, name, type);
2777 if (context == NULL)
2780 idmap_take(gprs->pid_map, id);
2782 strcpy(context->context.username, username);
2783 strcpy(context->context.password, password);
2784 strcpy(context->context.apn, apn);
2785 context->context.proto = proto;
2787 if (msgproxy != NULL)
2788 strcpy(context->message_proxy, msgproxy);
2790 if (msgcenter != NULL)
2791 strcpy(context->message_center, msgcenter);
2793 if (context_dbus_register(context) == FALSE)
2796 gprs->last_context_id = id;
2798 gprs->contexts = g_slist_append(gprs->contexts, context);
2802 write_context_settings(gprs, context);
2803 g_key_file_remove_group(gprs->settings, group, NULL);
2819 static void gprs_load_settings(struct ofono_gprs *gprs, const char *imsi)
2822 gboolean legacy = FALSE;
2826 gprs->settings = storage_open(imsi, SETTINGS_STORE);
2828 if (gprs->settings == NULL)
2831 gprs->imsi = g_strdup(imsi);
2834 gprs->powered = g_key_file_get_boolean(gprs->settings, SETTINGS_GROUP,
2838 * If any error occurs, simply switch to defaults.
2839 * Default to Powered = True
2840 * and RoamingAllowed = False
2843 g_error_free(error);
2844 gprs->powered = TRUE;
2845 g_key_file_set_boolean(gprs->settings, SETTINGS_GROUP,
2846 "Powered", gprs->powered);
2850 gprs->roaming_allowed = g_key_file_get_boolean(gprs->settings,
2856 g_error_free(error);
2857 gprs->roaming_allowed = FALSE;
2858 g_key_file_set_boolean(gprs->settings, SETTINGS_GROUP,
2860 gprs->roaming_allowed);
2863 groups = g_key_file_get_groups(gprs->settings, NULL);
2865 for (i = 0; groups[i]; i++) {
2866 if (g_str_equal(groups[i], SETTINGS_GROUP))
2869 if (!g_str_has_prefix(groups[i], "context")) {
2870 if (!g_str_has_prefix(groups[i], "primarycontext"))
2876 if (load_context(gprs, groups[i]) == TRUE)
2880 g_key_file_remove_group(gprs->settings, groups[i], NULL);
2886 storage_sync(imsi, SETTINGS_STORE, gprs->settings);
2889 static void provision_context(const struct ofono_gprs_provision_data *ap,
2890 struct ofono_gprs *gprs)
2893 struct pri_context *context = NULL;
2899 if (ap->name && strlen(ap->name) > MAX_CONTEXT_NAME_LENGTH)
2902 if (ap->apn == NULL || strlen(ap->apn) > OFONO_GPRS_MAX_APN_LENGTH)
2905 if (is_valid_apn(ap->apn) == FALSE)
2909 strlen(ap->username) > OFONO_GPRS_MAX_USERNAME_LENGTH)
2913 strlen(ap->password) > OFONO_GPRS_MAX_PASSWORD_LENGTH)
2916 if (ap->message_proxy &&
2917 strlen(ap->message_proxy) > MAX_MESSAGE_PROXY_LENGTH)
2920 if (ap->message_center &&
2921 strlen(ap->message_center) > MAX_MESSAGE_CENTER_LENGTH)
2924 if (gprs->last_context_id)
2925 id = idmap_alloc_next(gprs->pid_map, gprs->last_context_id);
2927 id = idmap_alloc(gprs->pid_map);
2929 if (id > idmap_get_max(gprs->pid_map))
2932 context = pri_context_create(gprs, ap->name, ap->type);
2933 if (context == NULL) {
2934 idmap_put(gprs->pid_map, id);
2940 if (ap->username != NULL)
2941 strcpy(context->context.username, ap->username);
2943 if (ap->password != NULL)
2944 strcpy(context->context.password, ap->password);
2946 strcpy(context->context.apn, ap->apn);
2947 context->context.proto = ap->proto;
2949 if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
2950 if (ap->message_proxy != NULL)
2951 strcpy(context->message_proxy, ap->message_proxy);
2953 if (ap->message_center != NULL)
2954 strcpy(context->message_center, ap->message_center);
2957 if (context_dbus_register(context) == FALSE)
2960 gprs->last_context_id = id;
2962 if (gprs->settings) {
2963 write_context_settings(gprs, context);
2964 storage_sync(gprs->imsi, SETTINGS_STORE, gprs->settings);
2967 gprs->contexts = g_slist_append(gprs->contexts, context);
2970 static void provision_contexts(struct ofono_gprs *gprs, const char *mcc,
2971 const char *mnc, const char *spn)
2973 struct ofono_gprs_provision_data *settings;
2977 if (__ofono_gprs_provision_get_settings(mcc, mnc, spn,
2978 &settings, &count) == FALSE) {
2979 ofono_warn("Provisioning failed");
2983 for (i = 0; i < count; i++)
2984 provision_context(&settings[i], gprs);
2986 __ofono_gprs_provision_free_settings(settings, count);
2989 static void ofono_gprs_finish_register(struct ofono_gprs *gprs)
2991 DBusConnection *conn = ofono_dbus_get_connection();
2992 struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
2993 const char *path = __ofono_atom_get_path(gprs->atom);
2995 if (gprs->contexts == NULL) /* Automatic provisioning failed */
2996 add_context(gprs, NULL, OFONO_GPRS_CONTEXT_TYPE_INTERNET);
2998 if (!g_dbus_register_interface(conn, path,
2999 OFONO_CONNECTION_MANAGER_INTERFACE,
3000 manager_methods, manager_signals, NULL,
3002 ofono_error("Could not create %s interface",
3003 OFONO_CONNECTION_MANAGER_INTERFACE);
3005 free_contexts(gprs);
3009 ofono_modem_add_interface(modem,
3010 OFONO_CONNECTION_MANAGER_INTERFACE);
3012 gprs->netreg_watch = __ofono_modem_add_atom_watch(modem,
3013 OFONO_ATOM_TYPE_NETREG,
3014 netreg_watch, gprs, NULL);
3016 __ofono_atom_register(gprs->atom, gprs_unregister);
3019 static void spn_read_cb(const char *spn, const char *dc, void *data)
3021 struct ofono_gprs *gprs = data;
3022 struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
3023 struct ofono_sim *sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem);
3025 provision_contexts(gprs, ofono_sim_get_mcc(sim),
3026 ofono_sim_get_mnc(sim), spn);
3028 ofono_sim_remove_spn_watch(sim, &gprs->spn_watch);
3030 ofono_gprs_finish_register(gprs);
3033 void ofono_gprs_register(struct ofono_gprs *gprs)
3035 struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
3036 struct ofono_sim *sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem);
3041 gprs_load_settings(gprs, ofono_sim_get_imsi(sim));
3046 ofono_sim_add_spn_watch(sim, &gprs->spn_watch, spn_read_cb, gprs, NULL);
3050 ofono_gprs_finish_register(gprs);
3053 void ofono_gprs_remove(struct ofono_gprs *gprs)
3055 __ofono_atom_free(gprs->atom);
3058 void ofono_gprs_set_data(struct ofono_gprs *gprs, void *data)
3060 gprs->driver_data = data;
3063 void *ofono_gprs_get_data(struct ofono_gprs *gprs)
3065 return gprs->driver_data;