Upgrade ofono to 1.11 and merge to 2.0alpha
[profile/ivi/ofono.git] / src / gprs.c
1 /*
2  *
3  *  oFono - Open Source Telephony
4  *
5  *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
6  *
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.
10  *
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.
15  *
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
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <string.h>
27 #include <stdio.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <sys/ioctl.h>
32 #include <sys/socket.h>
33 #include <net/if.h>
34 #include <net/route.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
37
38 #include <glib.h>
39 #include <gdbus.h>
40
41 #include "ofono.h"
42
43 #include "common.h"
44 #include "storage.h"
45 #include "idmap.h"
46 #include "simutil.h"
47 #include "util.h"
48
49 #define GPRS_FLAG_ATTACHING 0x1
50 #define GPRS_FLAG_RECHECK 0x2
51 #define GPRS_FLAG_ATTACHED_UPDATE 0x4
52
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
60
61 /* 27.007 Section 7.29 */
62 enum packet_bearer {
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,
71 };
72
73 struct ofono_gprs {
74         GSList *contexts;
75         ofono_bool_t attached;
76         ofono_bool_t driver_attached;
77         ofono_bool_t roaming_allowed;
78         ofono_bool_t powered;
79         ofono_bool_t suspended;
80         int status;
81         int flags;
82         int bearer;
83         guint suspend_timeout;
84         struct idmap *pid_map;
85         unsigned int last_context_id;
86         struct idmap *cid_map;
87         int netreg_status;
88         struct ofono_netreg *netreg;
89         unsigned int netreg_watch;
90         unsigned int status_watch;
91         GKeyFile *settings;
92         char *imsi;
93         DBusMessage *pending;
94         GSList *context_drivers;
95         const struct ofono_gprs_driver *driver;
96         void *driver_data;
97         struct ofono_atom *atom;
98         unsigned int spn_watch;
99 };
100
101 struct ipv4_settings {
102         ofono_bool_t static_ip;
103         char *ip;
104         char *netmask;
105         char *gateway;
106         char **dns;
107         char *proxy;
108 };
109
110 struct ipv6_settings {
111         char *ip;
112         unsigned char prefix_len;
113         char *gateway;
114         char **dns;
115 };
116
117 struct context_settings {
118         char *interface;
119         struct ipv4_settings *ipv4;
120         struct ipv6_settings *ipv6;
121 };
122
123 struct ofono_gprs_context {
124         struct ofono_gprs *gprs;
125         enum ofono_gprs_context_type type;
126         ofono_bool_t inuse;
127         const struct ofono_gprs_context_driver *driver;
128         void *driver_data;
129         struct context_settings *settings;
130         struct ofono_atom *atom;
131 };
132
133 struct pri_context {
134         ofono_bool_t active;
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];
139         unsigned int id;
140         char *path;
141         char *key;
142         char *proxy_host;
143         uint16_t proxy_port;
144         DBusMessage *pending;
145         struct ofono_gprs_primary_context context;
146         struct ofono_gprs_context *context_driver;
147         struct ofono_gprs *gprs;
148 };
149
150 static void gprs_netreg_update(struct ofono_gprs *gprs);
151 static void gprs_deactivate_next(struct ofono_gprs *gprs);
152
153 static GSList *g_drivers = NULL;
154 static GSList *g_context_drivers = NULL;
155
156 const char *packet_bearer_to_string(int bearer)
157 {
158         switch (bearer) {
159         case PACKET_BEARER_NONE:
160                 return "none";
161         case PACKET_BEARER_GPRS:
162                 return "gprs";
163         case PACKET_BEARER_EGPRS:
164                 return "edge";
165         case PACKET_BEARER_UMTS:
166                 return "umts";
167         case PACKET_BEARER_HSUPA:
168                 return "hsupa";
169         case PACKET_BEARER_HSDPA:
170                 return "hsdpa";
171         case PACKET_BEARER_HSUPA_HSDPA:
172                 return "hspa";
173         case PACKET_BEARER_EPS:
174                 return "lte";
175         }
176         return "";
177 }
178
179 static const char *gprs_context_default_name(enum ofono_gprs_context_type type)
180 {
181         switch (type) {
182         case OFONO_GPRS_CONTEXT_TYPE_ANY:
183                 return NULL;
184         case OFONO_GPRS_CONTEXT_TYPE_INTERNET:
185                 return "Internet";
186         case OFONO_GPRS_CONTEXT_TYPE_MMS:
187                 return "MMS";
188         case OFONO_GPRS_CONTEXT_TYPE_WAP:
189                 return "WAP";
190         case OFONO_GPRS_CONTEXT_TYPE_IMS:
191                 return "IMS";
192         }
193
194         return NULL;
195 }
196
197 static const char *gprs_context_type_to_string(
198                                         enum ofono_gprs_context_type type)
199 {
200         switch (type) {
201         case OFONO_GPRS_CONTEXT_TYPE_ANY:
202                 return NULL;
203         case OFONO_GPRS_CONTEXT_TYPE_INTERNET:
204                 return "internet";
205         case OFONO_GPRS_CONTEXT_TYPE_MMS:
206                 return "mms";
207         case OFONO_GPRS_CONTEXT_TYPE_WAP:
208                 return "wap";
209         case OFONO_GPRS_CONTEXT_TYPE_IMS:
210                 return "ims";
211         }
212
213         return NULL;
214 }
215
216 static gboolean gprs_context_string_to_type(const char *str,
217                                         enum ofono_gprs_context_type *out)
218 {
219         if (g_str_equal(str, "internet")) {
220                 *out = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
221                 return TRUE;
222         } else if (g_str_equal(str, "wap")) {
223                 *out = OFONO_GPRS_CONTEXT_TYPE_WAP;
224                 return TRUE;
225         } else if (g_str_equal(str, "mms")) {
226                 *out = OFONO_GPRS_CONTEXT_TYPE_MMS;
227                 return TRUE;
228         } else if (g_str_equal(str, "ims")) {
229                 *out = OFONO_GPRS_CONTEXT_TYPE_IMS;
230                 return TRUE;
231         }
232
233         return FALSE;
234 }
235
236 static const char *gprs_proto_to_string(enum ofono_gprs_proto proto)
237 {
238         switch (proto) {
239         case OFONO_GPRS_PROTO_IP:
240                 return "ip";
241         case OFONO_GPRS_PROTO_IPV6:
242                 return "ipv6";
243         case OFONO_GPRS_PROTO_IPV4V6:
244                 return "dual";
245         };
246
247         return NULL;
248 }
249
250 static gboolean gprs_proto_from_string(const char *str,
251                                         enum ofono_gprs_proto *proto)
252 {
253         if (g_str_equal(str, "ip")) {
254                 *proto = OFONO_GPRS_PROTO_IP;
255                 return TRUE;
256         } else if (g_str_equal(str, "ipv6")) {
257                 *proto = OFONO_GPRS_PROTO_IPV6;
258                 return TRUE;
259         } else if (g_str_equal(str, "dual")) {
260                 *proto = OFONO_GPRS_PROTO_IPV4V6;
261                 return TRUE;
262         }
263
264         return FALSE;
265 }
266
267 static unsigned int gprs_cid_alloc(struct ofono_gprs *gprs)
268 {
269         return idmap_alloc(gprs->cid_map);
270 }
271
272 static void gprs_cid_release(struct ofono_gprs *gprs, unsigned int id)
273 {
274         idmap_put(gprs->cid_map, id);
275 }
276
277 static gboolean assign_context(struct pri_context *ctx)
278 {
279         struct idmap *cidmap = ctx->gprs->cid_map;
280         GSList *l;
281
282         if (cidmap == NULL)
283                 return FALSE;
284
285         ctx->context.cid = gprs_cid_alloc(ctx->gprs);
286         if (ctx->context.cid == 0)
287                 return FALSE;
288
289         for (l = ctx->gprs->context_drivers; l; l = l->next) {
290                 struct ofono_gprs_context *gc = l->data;
291
292                 if (gc->inuse == TRUE)
293                         continue;
294
295                 if (gc->driver == NULL)
296                         continue;
297
298                 if (gc->driver->activate_primary == NULL ||
299                                 gc->driver->deactivate_primary == NULL)
300                         continue;
301
302                 if (gc->type != OFONO_GPRS_CONTEXT_TYPE_ANY &&
303                                 gc->type != ctx->type)
304                         continue;
305
306                 ctx->context_driver = gc;
307                 ctx->context_driver->inuse = TRUE;
308
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);
312
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);
316
317                 return TRUE;
318         }
319
320         return FALSE;
321 }
322
323 static void release_context(struct pri_context *ctx)
324 {
325         if (ctx == NULL || ctx->gprs == NULL || ctx->context_driver == NULL)
326                 return;
327
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;
332         ctx->active = FALSE;
333 }
334
335 static struct pri_context *gprs_context_by_path(struct ofono_gprs *gprs,
336                                                 const char *ctx_path)
337 {
338         GSList *l;
339
340         for (l = gprs->contexts; l; l = l->next) {
341                 struct pri_context *ctx = l->data;
342
343                 if (g_str_equal(ctx_path, ctx->path))
344                         return ctx;
345         }
346
347         return NULL;
348 }
349
350 static void context_settings_free(struct context_settings *settings)
351 {
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);
358
359                 g_free(settings->ipv4);
360                 settings->ipv4 = NULL;
361         }
362
363         if (settings->ipv6) {
364                 g_free(settings->ipv6->ip);
365                 g_free(settings->ipv6->gateway);
366                 g_strfreev(settings->ipv6->dns);
367
368                 g_free(settings->ipv6);
369                 settings->ipv6 = NULL;
370         }
371
372         g_free(settings->interface);
373         settings->interface = NULL;
374 }
375
376 static void context_settings_append_ipv4(struct context_settings *settings,
377                                                 DBusMessageIter *iter)
378 {
379         DBusMessageIter variant;
380         DBusMessageIter array;
381         char typesig[5];
382         char arraysig[6];
383         const char *method;
384
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';
391
392         dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
393                                                 arraysig, &variant);
394
395         dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
396                                                 typesig, &array);
397         if (settings == NULL || settings->ipv4 == NULL)
398                 goto done;
399
400         ofono_dbus_dict_append(&array, "Interface",
401                                 DBUS_TYPE_STRING, &settings->interface);
402
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);
407                 goto done;
408         }
409
410         if (settings->ipv4->static_ip == TRUE)
411                 method = "static";
412         else
413                 method = "dhcp";
414
415         ofono_dbus_dict_append(&array, "Method", DBUS_TYPE_STRING, &method);
416
417         if (settings->ipv4->ip)
418                 ofono_dbus_dict_append(&array, "Address", DBUS_TYPE_STRING,
419                                         &settings->ipv4->ip);
420
421         if (settings->ipv4->netmask)
422                 ofono_dbus_dict_append(&array, "Netmask", DBUS_TYPE_STRING,
423                                         &settings->ipv4->netmask);
424
425         if (settings->ipv4->gateway)
426                 ofono_dbus_dict_append(&array, "Gateway", DBUS_TYPE_STRING,
427                                         &settings->ipv4->gateway);
428
429         if (settings->ipv4->dns)
430                 ofono_dbus_dict_append_array(&array, "DomainNameServers",
431                                                 DBUS_TYPE_STRING,
432                                                 &settings->ipv4->dns);
433
434 done:
435         dbus_message_iter_close_container(&variant, &array);
436
437         dbus_message_iter_close_container(iter, &variant);
438 }
439
440 static void context_settings_append_ipv4_dict(struct context_settings *settings,
441                                                 DBusMessageIter *dict)
442 {
443         DBusMessageIter entry;
444         const char *key = "Settings";
445
446         dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
447                                                 NULL, &entry);
448
449         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
450
451         context_settings_append_ipv4(settings, &entry);
452
453         dbus_message_iter_close_container(dict, &entry);
454 }
455
456 static void context_settings_append_ipv6(struct context_settings *settings,
457                                                 DBusMessageIter *iter)
458 {
459         DBusMessageIter variant;
460         DBusMessageIter array;
461         char typesig[5];
462         char arraysig[6];
463
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';
470
471         dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
472                                                 arraysig, &variant);
473
474         dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
475                                                 typesig, &array);
476         if (settings == NULL || settings->ipv6 == NULL)
477                 goto done;
478
479         ofono_dbus_dict_append(&array, "Interface",
480                                 DBUS_TYPE_STRING, &settings->interface);
481
482         if (settings->ipv6->ip)
483                 ofono_dbus_dict_append(&array, "Address", DBUS_TYPE_STRING,
484                                         &settings->ipv6->ip);
485
486         if (settings->ipv6->prefix_len)
487                 ofono_dbus_dict_append(&array, "PrefixLength", DBUS_TYPE_BYTE,
488                                         &settings->ipv6->prefix_len);
489
490         if (settings->ipv6->gateway)
491                 ofono_dbus_dict_append(&array, "Gateway", DBUS_TYPE_STRING,
492                                         &settings->ipv6->gateway);
493
494         if (settings->ipv6->dns)
495                 ofono_dbus_dict_append_array(&array, "DomainNameServers",
496                                                 DBUS_TYPE_STRING,
497                                                 &settings->ipv6->dns);
498
499 done:
500         dbus_message_iter_close_container(&variant, &array);
501
502         dbus_message_iter_close_container(iter, &variant);
503 }
504
505 static void context_settings_append_ipv6_dict(struct context_settings *settings,
506                                                 DBusMessageIter *dict)
507 {
508         DBusMessageIter entry;
509         const char *key = "IPv6.Settings";
510
511         dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
512                                                 NULL, &entry);
513
514         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
515
516         context_settings_append_ipv6(settings, &entry);
517
518         dbus_message_iter_close_container(dict, &entry);
519 }
520
521 static void signal_settings(struct pri_context *ctx, const char *prop,
522                 void (*append)(struct context_settings *, DBusMessageIter *))
523
524 {
525         DBusConnection *conn = ofono_dbus_get_connection();
526         const char *path = ctx->path;
527         DBusMessage *signal;
528         DBusMessageIter iter;
529         struct context_settings *settings;
530
531         signal = dbus_message_new_signal(path,
532                                         OFONO_CONNECTION_CONTEXT_INTERFACE,
533                                         "PropertyChanged");
534
535         if (signal == NULL)
536                 return;
537
538         dbus_message_iter_init_append(signal, &iter);
539         dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &prop);
540
541         if (ctx->context_driver)
542                 settings = ctx->context_driver->settings;
543         else
544                 settings = NULL;
545
546         append(settings, &iter);
547         g_dbus_send_message(conn, signal);
548 }
549
550 static void pri_context_signal_settings(struct pri_context *ctx,
551                                         gboolean ipv4, gboolean ipv6)
552 {
553         if (ipv4)
554                 signal_settings(ctx, "Settings",
555                                 context_settings_append_ipv4);
556
557         if (ipv6)
558                 signal_settings(ctx, "IPv6.Settings",
559                                 context_settings_append_ipv6);
560 }
561
562 static void pri_parse_proxy(struct pri_context *ctx, const char *proxy)
563 {
564         char *scheme, *host, *port, *path;
565
566         scheme = g_strdup(proxy);
567         if (scheme == NULL)
568                 return;
569
570         host = strstr(scheme, "://");
571         if (host != NULL) {
572                 *host = '\0';
573                 host += 3;
574
575                 if (strcasecmp(scheme, "https") == 0)
576                         ctx->proxy_port = 443;
577                 else if (strcasecmp(scheme, "http") == 0)
578                         ctx->proxy_port = 80;
579                 else {
580                         g_free(scheme);
581                         return;
582                 }
583         } else {
584                 host = scheme;
585                 ctx->proxy_port = 80;
586         }
587
588         path = strchr(host, '/');
589         if (path != NULL)
590                 *(path++) = '\0';
591
592         port = strrchr(host, ':');
593         if (port != NULL) {
594                 char *end;
595                 int tmp = strtol(port + 1, &end, 10);
596
597                 if (*end == '\0') {
598                         *port = '\0';
599                         ctx->proxy_port = tmp;
600                 }
601         }
602
603         g_free(ctx->proxy_host);
604         ctx->proxy_host = g_strdup(host);
605
606         g_free(scheme);
607 }
608
609 static void pri_ifupdown(const char *interface, ofono_bool_t active)
610 {
611         struct ifreq ifr;
612         int sk;
613
614         if (interface == NULL)
615                 return;
616
617         sk = socket(PF_INET, SOCK_DGRAM, 0);
618         if (sk < 0)
619                 return;
620
621         memset(&ifr, 0, sizeof(ifr));
622         strncpy(ifr.ifr_name, interface, IFNAMSIZ);
623
624         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0)
625                 goto done;
626
627         if (active == TRUE) {
628                 if (ifr.ifr_flags & IFF_UP)
629                         goto done;
630                 ifr.ifr_flags |= IFF_UP;
631         } else {
632                 if (!(ifr.ifr_flags & IFF_UP))
633                         goto done;
634                 ifr.ifr_flags &= ~IFF_UP;
635         }
636
637         if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
638                 ofono_error("Failed to change interface flags");
639
640 done:
641         close(sk);
642 }
643
644 static void pri_set_ipv4_addr(const char *interface, const char *address)
645 {
646         struct ifreq ifr;
647         struct sockaddr_in addr;
648         int sk;
649
650         if (interface == NULL)
651                 return;
652
653         sk = socket(PF_INET, SOCK_DGRAM, 0);
654         if (sk < 0)
655                 return;
656
657         memset(&ifr, 0, sizeof(ifr));
658         strncpy(ifr.ifr_name, interface, IFNAMSIZ);
659
660         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0)
661                 goto done;
662
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));
667
668         if (ioctl(sk, SIOCSIFADDR, &ifr) < 0) {
669                 ofono_error("Failed to set interface address");
670                 goto done;
671         }
672
673         if (address == NULL)
674                 goto done;
675
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));
680
681         if (ioctl(sk, SIOCSIFNETMASK, &ifr) < 0)
682                 ofono_error("Failed to set interface netmask");
683
684 done:
685         close(sk);
686 }
687
688 static void pri_setproxy(const char *interface, const char *proxy)
689 {
690         struct rtentry rt;
691         struct sockaddr_in addr;
692         int sk;
693
694         if (interface == NULL)
695                 return;
696
697         sk = socket(PF_INET, SOCK_DGRAM, 0);
698         if (sk < 0)
699                 return;
700
701         memset(&rt, 0, sizeof(rt));
702         rt.rt_flags = RTF_UP | RTF_HOST;
703         rt.rt_dev = (char *) interface;
704
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));
709
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));
714
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));
719
720         if (ioctl(sk, SIOCADDRT, &rt) < 0)
721                 ofono_error("Failed to add proxy host route");
722
723         close(sk);
724 }
725
726 static void pri_reset_context_settings(struct pri_context *ctx)
727 {
728         struct context_settings *settings;
729         char *interface;
730         gboolean signal_ipv4;
731         gboolean signal_ipv6;
732
733         if (ctx->context_driver == NULL)
734                 return;
735
736         settings = ctx->context_driver->settings;
737
738         interface = settings->interface;
739         settings->interface = NULL;
740
741         signal_ipv4 = settings->ipv4 != NULL;
742         signal_ipv6 = settings->ipv6 != NULL;
743
744         context_settings_free(settings);
745
746         pri_context_signal_settings(ctx, signal_ipv4, signal_ipv6);
747
748         if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
749                 pri_set_ipv4_addr(interface, NULL);
750
751                 g_free(ctx->proxy_host);
752                 ctx->proxy_host = NULL;
753                 ctx->proxy_port = 0;
754         }
755
756         pri_ifupdown(interface, FALSE);
757
758         g_free(interface);
759 }
760
761 static void pri_update_mms_context_settings(struct pri_context *ctx)
762 {
763         struct ofono_gprs_context *gc = ctx->context_driver;
764         struct context_settings *settings = gc->settings;
765
766         if (ctx->message_proxy)
767                 settings->ipv4->proxy = g_strdup(ctx->message_proxy);
768
769         pri_parse_proxy(ctx, ctx->message_proxy);
770
771         DBG("proxy %s port %u", ctx->proxy_host, ctx->proxy_port);
772
773         pri_set_ipv4_addr(settings->interface, settings->ipv4->ip);
774
775         if (ctx->proxy_host)
776                 pri_setproxy(settings->interface, ctx->proxy_host);
777 }
778
779 static void append_context_properties(struct pri_context *ctx,
780                                         DBusMessageIter *dict)
781 {
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;
785         dbus_bool_t value;
786         const char *strvalue;
787         struct context_settings *settings;
788
789         ofono_dbus_dict_append(dict, "Name", DBUS_TYPE_STRING, &name);
790
791         value = ctx->active;
792         ofono_dbus_dict_append(dict, "Active", DBUS_TYPE_BOOLEAN, &value);
793
794         ofono_dbus_dict_append(dict, "Type", DBUS_TYPE_STRING, &type);
795
796         ofono_dbus_dict_append(dict, "Protocol", DBUS_TYPE_STRING, &proto);
797
798         strvalue = ctx->context.apn;
799         ofono_dbus_dict_append(dict, "AccessPointName", DBUS_TYPE_STRING,
800                                 &strvalue);
801
802         strvalue = ctx->context.username;
803         ofono_dbus_dict_append(dict, "Username", DBUS_TYPE_STRING,
804                                 &strvalue);
805
806         strvalue = ctx->context.password;
807         ofono_dbus_dict_append(dict, "Password", DBUS_TYPE_STRING,
808                                 &strvalue);
809
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);
814
815                 strvalue = ctx->message_center;
816                 ofono_dbus_dict_append(dict, "MessageCenter",
817                                         DBUS_TYPE_STRING, &strvalue);
818         }
819
820         if (ctx->context_driver)
821                 settings = ctx->context_driver->settings;
822         else
823                 settings = NULL;
824
825         context_settings_append_ipv4_dict(settings, dict);
826         context_settings_append_ipv6_dict(settings, dict);
827 }
828
829 static DBusMessage *pri_get_properties(DBusConnection *conn,
830                                         DBusMessage *msg, void *data)
831 {
832         struct pri_context *ctx = data;
833         DBusMessage *reply;
834         DBusMessageIter iter;
835         DBusMessageIter dict;
836
837         reply = dbus_message_new_method_return(msg);
838         if (reply == NULL)
839                 return NULL;
840
841         dbus_message_iter_init_append(reply, &iter);
842
843         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
844                                         OFONO_PROPERTIES_ARRAY_SIGNATURE,
845                                         &dict);
846         append_context_properties(ctx, &dict);
847         dbus_message_iter_close_container(&iter, &dict);
848
849         return reply;
850 }
851
852 static void pri_activate_callback(const struct ofono_error *error, void *data)
853 {
854         struct pri_context *ctx = data;
855         struct ofono_gprs_context *gc = ctx->context_driver;
856         DBusConnection *conn = ofono_dbus_get_connection();
857         dbus_bool_t value;
858
859         DBG("%p", ctx);
860
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);
868                 return;
869         }
870
871         ctx->active = TRUE;
872         __ofono_dbus_pending_reply(&ctx->pending,
873                                 dbus_message_new_method_return(ctx->pending));
874
875         if (gc->settings->interface != NULL) {
876                 pri_ifupdown(gc->settings->interface, TRUE);
877
878                 if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS &&
879                                 gc->settings->ipv4)
880                         pri_update_mms_context_settings(ctx);
881
882                 pri_context_signal_settings(ctx, gc->settings->ipv4 != NULL,
883                                                 gc->settings->ipv6 != NULL);
884         }
885
886         value = ctx->active;
887         ofono_dbus_signal_property_changed(conn, ctx->path,
888                                         OFONO_CONNECTION_CONTEXT_INTERFACE,
889                                         "Active", DBUS_TYPE_BOOLEAN, &value);
890 }
891
892 static void pri_deactivate_callback(const struct ofono_error *error, void *data)
893 {
894         struct pri_context *ctx = data;
895         DBusConnection *conn = ofono_dbus_get_connection();
896         dbus_bool_t value;
897
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));
903                 return;
904         }
905
906         __ofono_dbus_pending_reply(&ctx->pending,
907                                 dbus_message_new_method_return(ctx->pending));
908
909         pri_reset_context_settings(ctx);
910         release_context(ctx);
911
912         value = ctx->active;
913         ofono_dbus_signal_property_changed(conn, ctx->path,
914                                         OFONO_CONNECTION_CONTEXT_INTERFACE,
915                                         "Active", DBUS_TYPE_BOOLEAN, &value);
916 }
917
918 static DBusMessage *pri_set_apn(struct pri_context *ctx, DBusConnection *conn,
919                                 DBusMessage *msg, const char *apn)
920 {
921         GKeyFile *settings = ctx->gprs->settings;
922
923         if (strlen(apn) > OFONO_GPRS_MAX_APN_LENGTH)
924                 return __ofono_error_invalid_format(msg);
925
926         if (g_str_equal(apn, ctx->context.apn))
927                 return dbus_message_new_method_return(msg);
928
929         if (is_valid_apn(apn) == FALSE)
930                 return __ofono_error_invalid_format(msg);
931
932         strcpy(ctx->context.apn, apn);
933
934         if (settings) {
935                 g_key_file_set_string(settings, ctx->key,
936                                         "AccessPointName", apn);
937                 storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
938         }
939
940         g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
941
942         ofono_dbus_signal_property_changed(conn, ctx->path,
943                                         OFONO_CONNECTION_CONTEXT_INTERFACE,
944                                         "AccessPointName",
945                                         DBUS_TYPE_STRING, &apn);
946
947         return NULL;
948 }
949
950 static DBusMessage *pri_set_username(struct pri_context *ctx,
951                                         DBusConnection *conn, DBusMessage *msg,
952                                         const char *username)
953 {
954         GKeyFile *settings = ctx->gprs->settings;
955
956         if (strlen(username) > OFONO_GPRS_MAX_USERNAME_LENGTH)
957                 return __ofono_error_invalid_format(msg);
958
959         if (g_str_equal(username, ctx->context.username))
960                 return dbus_message_new_method_return(msg);
961
962         strcpy(ctx->context.username, username);
963
964         if (settings) {
965                 g_key_file_set_string(settings, ctx->key,
966                                         "Username", username);
967                 storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
968         }
969
970         g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
971
972         ofono_dbus_signal_property_changed(conn, ctx->path,
973                                         OFONO_CONNECTION_CONTEXT_INTERFACE,
974                                         "Username",
975                                         DBUS_TYPE_STRING, &username);
976
977         return NULL;
978 }
979
980 static DBusMessage *pri_set_password(struct pri_context *ctx,
981                                         DBusConnection *conn, DBusMessage *msg,
982                                         const char *password)
983 {
984         GKeyFile *settings = ctx->gprs->settings;
985
986         if (strlen(password) > OFONO_GPRS_MAX_PASSWORD_LENGTH)
987                 return __ofono_error_invalid_format(msg);
988
989         if (g_str_equal(password, ctx->context.password))
990                 return dbus_message_new_method_return(msg);
991
992         strcpy(ctx->context.password, password);
993
994         if (settings) {
995                 g_key_file_set_string(settings, ctx->key,
996                                         "Password", password);
997                 storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
998         }
999
1000         g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1001
1002         ofono_dbus_signal_property_changed(conn, ctx->path,
1003                                         OFONO_CONNECTION_CONTEXT_INTERFACE,
1004                                         "Password",
1005                                         DBUS_TYPE_STRING, &password);
1006
1007         return NULL;
1008 }
1009
1010 static DBusMessage *pri_set_type(struct pri_context *ctx, DBusConnection *conn,
1011                                         DBusMessage *msg, const char *type)
1012 {
1013         GKeyFile *settings = ctx->gprs->settings;
1014         enum ofono_gprs_context_type context_type;
1015
1016         if (gprs_context_string_to_type(type, &context_type) == FALSE)
1017                 return __ofono_error_invalid_format(msg);
1018
1019         if (ctx->type == context_type)
1020                 return dbus_message_new_method_return(msg);
1021
1022         ctx->type = context_type;
1023
1024         if (settings) {
1025                 g_key_file_set_string(settings, ctx->key, "Type", type);
1026                 storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
1027         }
1028
1029         g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1030
1031         ofono_dbus_signal_property_changed(conn, ctx->path,
1032                                         OFONO_CONNECTION_CONTEXT_INTERFACE,
1033                                         "Type", DBUS_TYPE_STRING, &type);
1034
1035         return NULL;
1036 }
1037
1038 static DBusMessage *pri_set_proto(struct pri_context *ctx,
1039                                         DBusConnection *conn,
1040                                         DBusMessage *msg, const char *str)
1041 {
1042         GKeyFile *settings = ctx->gprs->settings;
1043         enum ofono_gprs_proto proto;
1044
1045         if (gprs_proto_from_string(str, &proto) == FALSE)
1046                 return __ofono_error_invalid_format(msg);
1047
1048         if (ctx->context.proto == proto)
1049                 return dbus_message_new_method_return(msg);
1050
1051         ctx->context.proto = proto;
1052
1053         if (settings) {
1054                 g_key_file_set_string(settings, ctx->key, "Protocol", str);
1055                 storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
1056         }
1057
1058         g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1059
1060         ofono_dbus_signal_property_changed(conn, ctx->path,
1061                                         OFONO_CONNECTION_CONTEXT_INTERFACE,
1062                                         "Protocol", DBUS_TYPE_STRING, &str);
1063
1064         return NULL;
1065 }
1066
1067 static DBusMessage *pri_set_name(struct pri_context *ctx, DBusConnection *conn,
1068                                         DBusMessage *msg, const char *name)
1069 {
1070         GKeyFile *settings = ctx->gprs->settings;
1071
1072         if (strlen(name) > MAX_CONTEXT_NAME_LENGTH)
1073                 return __ofono_error_invalid_format(msg);
1074
1075         if (ctx->name && g_str_equal(ctx->name, name))
1076                 return dbus_message_new_method_return(msg);
1077
1078         strcpy(ctx->name, name);
1079
1080         if (settings) {
1081                 g_key_file_set_string(settings, ctx->key, "Name", ctx->name);
1082                 storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
1083         }
1084
1085         g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1086
1087         ofono_dbus_signal_property_changed(conn, ctx->path,
1088                                         OFONO_CONNECTION_CONTEXT_INTERFACE,
1089                                         "Name", DBUS_TYPE_STRING, &name);
1090
1091         return NULL;
1092 }
1093
1094 static DBusMessage *pri_set_message_proxy(struct pri_context *ctx,
1095                                         DBusConnection *conn,
1096                                         DBusMessage *msg, const char *proxy)
1097 {
1098         GKeyFile *settings = ctx->gprs->settings;
1099
1100         if (strlen(proxy) > MAX_MESSAGE_PROXY_LENGTH)
1101                 return __ofono_error_invalid_format(msg);
1102
1103         if (ctx->message_proxy && g_str_equal(ctx->message_proxy, proxy))
1104                 return dbus_message_new_method_return(msg);
1105
1106         strcpy(ctx->message_proxy, proxy);
1107
1108         if (settings) {
1109                 g_key_file_set_string(settings, ctx->key, "MessageProxy",
1110                                                         ctx->message_proxy);
1111                 storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
1112         }
1113
1114         g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1115
1116         ofono_dbus_signal_property_changed(conn, ctx->path,
1117                                 OFONO_CONNECTION_CONTEXT_INTERFACE,
1118                                 "MessageProxy", DBUS_TYPE_STRING, &proxy);
1119
1120         return NULL;
1121 }
1122
1123 static DBusMessage *pri_set_message_center(struct pri_context *ctx,
1124                                         DBusConnection *conn,
1125                                         DBusMessage *msg, const char *center)
1126 {
1127         GKeyFile *settings = ctx->gprs->settings;
1128
1129         if (strlen(center) > MAX_MESSAGE_CENTER_LENGTH)
1130                 return __ofono_error_invalid_format(msg);
1131
1132         if (ctx->message_center && g_str_equal(ctx->message_center, center))
1133                 return dbus_message_new_method_return(msg);
1134
1135         strcpy(ctx->message_center, center);
1136
1137         if (settings) {
1138                 g_key_file_set_string(settings, ctx->key, "MessageCenter",
1139                                                         ctx->message_center);
1140                 storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
1141         }
1142
1143         g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1144
1145         ofono_dbus_signal_property_changed(conn, ctx->path,
1146                                 OFONO_CONNECTION_CONTEXT_INTERFACE,
1147                                 "MessageCenter", DBUS_TYPE_STRING, &center);
1148
1149         return NULL;
1150 }
1151
1152 static DBusMessage *pri_set_property(DBusConnection *conn,
1153                                         DBusMessage *msg, void *data)
1154 {
1155         struct pri_context *ctx = data;
1156         DBusMessageIter iter;
1157         DBusMessageIter var;
1158         const char *property;
1159         dbus_bool_t value;
1160         const char *str;
1161
1162         if (!dbus_message_iter_init(msg, &iter))
1163                 return __ofono_error_invalid_args(msg);
1164
1165         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
1166                 return __ofono_error_invalid_args(msg);
1167
1168         dbus_message_iter_get_basic(&iter, &property);
1169         dbus_message_iter_next(&iter);
1170
1171         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
1172                 return __ofono_error_invalid_args(msg);
1173
1174         dbus_message_iter_recurse(&iter, &var);
1175
1176         if (g_str_equal(property, "Active")) {
1177                 struct ofono_gprs_context *gc;
1178
1179                 if (ctx->gprs->pending)
1180                         return __ofono_error_busy(msg);
1181
1182                 if (ctx->pending)
1183                         return __ofono_error_busy(msg);
1184
1185                 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_BOOLEAN)
1186                         return __ofono_error_invalid_args(msg);
1187
1188                 dbus_message_iter_get_basic(&var, &value);
1189
1190                 if (ctx->active == (ofono_bool_t) value)
1191                         return dbus_message_new_method_return(msg);
1192
1193                 if (value && !ctx->gprs->attached)
1194                         return __ofono_error_not_attached(msg);
1195
1196                 if (ctx->gprs->flags & GPRS_FLAG_ATTACHING)
1197                         return __ofono_error_attach_in_progress(msg);
1198
1199                 if (value && assign_context(ctx) == FALSE)
1200                         return __ofono_error_not_implemented(msg);
1201
1202                 gc = ctx->context_driver;
1203
1204                 ctx->pending = dbus_message_ref(msg);
1205
1206                 if (value)
1207                         gc->driver->activate_primary(gc, &ctx->context,
1208                                                 pri_activate_callback, ctx);
1209                 else
1210                         gc->driver->deactivate_primary(gc, ctx->context.cid,
1211                                                 pri_deactivate_callback, ctx);
1212
1213                 return NULL;
1214         }
1215
1216         /* All other properties are read-only when context is active */
1217         if (ctx->active == TRUE)
1218                 return __ofono_error_in_use(msg);
1219
1220         if (!strcmp(property, "AccessPointName")) {
1221                 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
1222                         return __ofono_error_invalid_args(msg);
1223
1224                 dbus_message_iter_get_basic(&var, &str);
1225
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);
1230
1231                 dbus_message_iter_get_basic(&var, &str);
1232
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);
1237
1238                 dbus_message_iter_get_basic(&var, &str);
1239
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);
1244
1245                 dbus_message_iter_get_basic(&var, &str);
1246
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);
1251
1252                 dbus_message_iter_get_basic(&var, &str);
1253
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);
1258
1259                 dbus_message_iter_get_basic(&var, &str);
1260
1261                 return pri_set_name(ctx, conn, msg, str);
1262         }
1263
1264         if (ctx->type != OFONO_GPRS_CONTEXT_TYPE_MMS)
1265                 return __ofono_error_invalid_args(msg);
1266
1267         if (!strcmp(property, "MessageProxy")) {
1268                 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
1269                         return __ofono_error_invalid_args(msg);
1270
1271                 dbus_message_iter_get_basic(&var, &str);
1272
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);
1277
1278                 dbus_message_iter_get_basic(&var, &str);
1279
1280                 return pri_set_message_center(ctx, conn, msg, str);
1281         }
1282
1283         return __ofono_error_invalid_args(msg);
1284 }
1285
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) },
1293         { }
1294 };
1295
1296 static const GDBusSignalTable context_signals[] = {
1297         { GDBUS_SIGNAL("PropertyChanged",
1298                         GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
1299         { }
1300 };
1301
1302 static struct pri_context *pri_context_create(struct ofono_gprs *gprs,
1303                                         const char *name,
1304                                         enum ofono_gprs_context_type type)
1305 {
1306         struct pri_context *context = g_try_new0(struct pri_context, 1);
1307
1308         if (context == NULL)
1309                 return NULL;
1310
1311         if (name == NULL) {
1312                 name = gprs_context_default_name(type);
1313                 if (name == NULL) {
1314                         g_free(context);
1315                         return NULL;
1316                 }
1317         }
1318
1319         context->gprs = gprs;
1320         strcpy(context->name, name);
1321         context->type = type;
1322
1323         return context;
1324 }
1325
1326 static void pri_context_destroy(gpointer userdata)
1327 {
1328         struct pri_context *ctx = userdata;
1329
1330         g_free(ctx->proxy_host);
1331         g_free(ctx->path);
1332         g_free(ctx);
1333 }
1334
1335 static gboolean context_dbus_register(struct pri_context *ctx)
1336 {
1337         DBusConnection *conn = ofono_dbus_get_connection();
1338         char path[256];
1339         const char *basepath;
1340
1341         basepath = __ofono_atom_get_path(ctx->gprs->atom);
1342
1343         snprintf(path, sizeof(path), "%s/context%u", basepath, ctx->id);
1344
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);
1352
1353                 return FALSE;
1354         }
1355
1356         ctx->path = g_strdup(path);
1357         ctx->key = ctx->path + strlen(basepath) + 1;
1358
1359         return TRUE;
1360 }
1361
1362 static gboolean context_dbus_unregister(struct pri_context *ctx)
1363 {
1364         DBusConnection *conn = ofono_dbus_get_connection();
1365         char path[256];
1366
1367         if (ctx->active == TRUE) {
1368                 const char *interface =
1369                         ctx->context_driver->settings->interface;
1370
1371                 if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS)
1372                         pri_set_ipv4_addr(interface, NULL);
1373
1374                 pri_ifupdown(interface, FALSE);
1375         }
1376
1377         strcpy(path, ctx->path);
1378         idmap_put(ctx->gprs->pid_map, ctx->id);
1379
1380         return g_dbus_unregister_interface(conn, path,
1381                                         OFONO_CONNECTION_CONTEXT_INTERFACE);
1382 }
1383
1384 static void update_suspended_property(struct ofono_gprs *gprs,
1385                                 ofono_bool_t suspended)
1386 {
1387         DBusConnection *conn = ofono_dbus_get_connection();
1388         const char *path = __ofono_atom_get_path(gprs->atom);
1389         dbus_bool_t value = suspended;
1390
1391         if (gprs->suspend_timeout) {
1392                 g_source_remove(gprs->suspend_timeout);
1393                 gprs->suspend_timeout = 0;
1394         }
1395
1396         if (gprs->suspended == suspended)
1397                 return;
1398
1399         DBG("%s GPRS service %s", __ofono_atom_get_path(gprs->atom),
1400                 suspended ? "suspended" : "resumed");
1401
1402         gprs->suspended = suspended;
1403
1404         if (gprs->attached)
1405                 ofono_dbus_signal_property_changed(conn, path,
1406                                         OFONO_CONNECTION_MANAGER_INTERFACE,
1407                                         "Suspended", DBUS_TYPE_BOOLEAN, &value);
1408 }
1409
1410 static gboolean suspend_timeout(gpointer data)
1411 {
1412         struct ofono_gprs *gprs = data;
1413
1414         gprs->suspend_timeout = 0;
1415         update_suspended_property(gprs, TRUE);
1416         return FALSE;
1417 }
1418
1419 void ofono_gprs_suspend_notify(struct ofono_gprs *gprs, int cause)
1420 {
1421         switch (cause) {
1422         case GPRS_SUSPENDED_DETACHED:
1423         case GPRS_SUSPENDED_CALL:
1424         case GPRS_SUSPENDED_NO_COVERAGE:
1425                 update_suspended_property(gprs, TRUE);
1426                 break;
1427
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,
1433                                                         suspend_timeout,
1434                                                         gprs);
1435                 break;
1436         }
1437 }
1438
1439 void ofono_gprs_resume_notify(struct ofono_gprs *gprs)
1440 {
1441         update_suspended_property(gprs, FALSE);
1442 }
1443
1444 static gboolean have_active_contexts(struct ofono_gprs *gprs)
1445 {
1446         GSList *l;
1447         struct pri_context *ctx;
1448
1449         for (l = gprs->contexts; l; l = l->next) {
1450                 ctx = l->data;
1451
1452                 if (ctx->active == TRUE)
1453                         return TRUE;
1454         }
1455
1456         return FALSE;
1457 }
1458
1459 static void release_active_contexts(struct ofono_gprs *gprs)
1460 {
1461         GSList *l;
1462         struct pri_context *ctx;
1463
1464         for (l = gprs->contexts; l; l = l->next) {
1465                 struct ofono_gprs_context *gc;
1466
1467                 ctx = l->data;
1468
1469                 if (ctx->active == FALSE)
1470                         continue;
1471
1472                 /* This context is already being messed with */
1473                 if (ctx->pending)
1474                         continue;
1475
1476                 gc = ctx->context_driver;
1477
1478                 if (gc->driver->detach_shutdown != NULL)
1479                         gc->driver->detach_shutdown(gc, ctx->context.cid);
1480         }
1481 }
1482
1483 static void gprs_attached_update(struct ofono_gprs *gprs)
1484 {
1485         DBusConnection *conn = ofono_dbus_get_connection();
1486         const char *path;
1487         ofono_bool_t attached;
1488         dbus_bool_t value;
1489
1490         attached = gprs->driver_attached &&
1491                 (gprs->status == NETWORK_REGISTRATION_STATUS_REGISTERED ||
1492                         gprs->status == NETWORK_REGISTRATION_STATUS_ROAMING);
1493
1494         if (attached == gprs->attached)
1495                 return;
1496
1497         /*
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.
1502          */
1503         if (attached == FALSE) {
1504                 release_active_contexts(gprs);
1505                 gprs->bearer = -1;
1506         } else if (have_active_contexts(gprs) == TRUE) {
1507                 gprs->flags |= GPRS_FLAG_ATTACHED_UPDATE;
1508                 return;
1509         }
1510
1511         gprs->attached = attached;
1512
1513         path = __ofono_atom_get_path(gprs->atom);
1514         value = attached;
1515         ofono_dbus_signal_property_changed(conn, path,
1516                                 OFONO_CONNECTION_MANAGER_INTERFACE,
1517                                 "Attached", DBUS_TYPE_BOOLEAN, &value);
1518 }
1519
1520 static void registration_status_cb(const struct ofono_error *error,
1521                                         int status, void *data)
1522 {
1523         struct ofono_gprs *gprs = data;
1524
1525         DBG("%s error %d status %d", __ofono_atom_get_path(gprs->atom),
1526                 error->type, status);
1527
1528         gprs->flags &= ~GPRS_FLAG_ATTACHING;
1529
1530         if (error->type == OFONO_ERROR_TYPE_NO_ERROR)
1531                 ofono_gprs_status_notify(gprs, status);
1532         else
1533                 gprs_attached_update(gprs);
1534
1535         if (gprs->flags & GPRS_FLAG_RECHECK) {
1536                 gprs->flags &= ~GPRS_FLAG_RECHECK;
1537                 gprs_netreg_update(gprs);
1538         }
1539 }
1540
1541 static void gprs_attach_callback(const struct ofono_error *error, void *data)
1542 {
1543         struct ofono_gprs *gprs = data;
1544
1545         DBG("%s error = %d", __ofono_atom_get_path(gprs->atom), error->type);
1546
1547         if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
1548                 gprs->driver_attached = !gprs->driver_attached;
1549
1550         if (gprs->driver->attached_status == NULL) {
1551                 struct ofono_error status_error;
1552
1553                 status_error.type = OFONO_ERROR_TYPE_FAILURE;
1554                 status_error.error = 0;
1555
1556                 registration_status_cb(&status_error, -1, gprs);
1557                 return;
1558         }
1559
1560         gprs->driver->attached_status(gprs, registration_status_cb, gprs);
1561 }
1562
1563 static void gprs_netreg_removed(struct ofono_gprs *gprs)
1564 {
1565         gprs->netreg = NULL;
1566
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;
1571
1572         gprs_attached_update(gprs);
1573 }
1574
1575 static void gprs_netreg_update(struct ofono_gprs *gprs)
1576 {
1577         ofono_bool_t attach;
1578
1579         attach = gprs->netreg_status == NETWORK_REGISTRATION_STATUS_REGISTERED;
1580
1581         attach = attach || (gprs->roaming_allowed &&
1582                 gprs->netreg_status == NETWORK_REGISTRATION_STATUS_ROAMING);
1583
1584         attach = attach && gprs->powered;
1585
1586         if (gprs->driver_attached == attach)
1587                 return;
1588
1589         if (gprs->flags & GPRS_FLAG_ATTACHING) {
1590                 gprs->flags |= GPRS_FLAG_RECHECK;
1591                 return;
1592         }
1593
1594         gprs->flags |= GPRS_FLAG_ATTACHING;
1595
1596         gprs->driver->set_attached(gprs, attach, gprs_attach_callback, gprs);
1597         gprs->driver_attached = attach;
1598 }
1599
1600 static void netreg_status_changed(int status, int lac, int ci, int tech,
1601                                         const char *mcc, const char *mnc,
1602                                         void *data)
1603 {
1604         struct ofono_gprs *gprs = data;
1605
1606         DBG("%d", status);
1607
1608         if (gprs->netreg_status == status)
1609                 return;
1610
1611         gprs->netreg_status = status;
1612
1613         gprs_netreg_update(gprs);
1614 }
1615
1616 static DBusMessage *gprs_get_properties(DBusConnection *conn,
1617                                         DBusMessage *msg, void *data)
1618 {
1619         struct ofono_gprs *gprs = data;
1620         DBusMessage *reply;
1621         DBusMessageIter iter;
1622         DBusMessageIter dict;
1623         dbus_bool_t value;
1624
1625         reply = dbus_message_new_method_return(msg);
1626         if (reply == NULL)
1627                 return NULL;
1628
1629         dbus_message_iter_init_append(reply, &iter);
1630
1631         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1632                                         OFONO_PROPERTIES_ARRAY_SIGNATURE,
1633                                         &dict);
1634
1635         value = gprs->attached;
1636         ofono_dbus_dict_append(&dict, "Attached", DBUS_TYPE_BOOLEAN, &value);
1637
1638         if (gprs->bearer != -1) {
1639                 const char *bearer = packet_bearer_to_string(gprs->bearer);
1640
1641                 ofono_dbus_dict_append(&dict, "Bearer",
1642                                         DBUS_TYPE_STRING, &bearer);
1643         }
1644
1645         value = gprs->roaming_allowed;
1646         ofono_dbus_dict_append(&dict, "RoamingAllowed",
1647                                 DBUS_TYPE_BOOLEAN, &value);
1648
1649         value = gprs->powered;
1650         ofono_dbus_dict_append(&dict, "Powered", DBUS_TYPE_BOOLEAN, &value);
1651
1652         if (gprs->attached) {
1653                 value = gprs->suspended;
1654                 ofono_dbus_dict_append(&dict, "Suspended",
1655                                 DBUS_TYPE_BOOLEAN, &value);
1656         }
1657
1658         dbus_message_iter_close_container(&iter, &dict);
1659
1660         return reply;
1661 }
1662
1663 static DBusMessage *gprs_set_property(DBusConnection *conn,
1664                                         DBusMessage *msg, void *data)
1665 {
1666         struct ofono_gprs *gprs = data;
1667         DBusMessageIter iter;
1668         DBusMessageIter var;
1669         const char *property;
1670         dbus_bool_t value;
1671         const char *path;
1672
1673         if (gprs->pending)
1674                 return __ofono_error_busy(msg);
1675
1676         if (!dbus_message_iter_init(msg, &iter))
1677                 return __ofono_error_invalid_args(msg);
1678
1679         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
1680                 return __ofono_error_invalid_args(msg);
1681
1682         dbus_message_iter_get_basic(&iter, &property);
1683         dbus_message_iter_next(&iter);
1684
1685         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
1686                 return __ofono_error_invalid_args(msg);
1687
1688         dbus_message_iter_recurse(&iter, &var);
1689
1690         if (!strcmp(property, "RoamingAllowed")) {
1691                 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_BOOLEAN)
1692                         return __ofono_error_invalid_args(msg);
1693
1694                 dbus_message_iter_get_basic(&var, &value);
1695
1696                 if (gprs->roaming_allowed == (ofono_bool_t) value)
1697                         return dbus_message_new_method_return(msg);
1698
1699                 gprs->roaming_allowed = value;
1700
1701                 if (gprs->settings) {
1702                         g_key_file_set_integer(gprs->settings, SETTINGS_GROUP,
1703                                                 "RoamingAllowed",
1704                                                 gprs->roaming_allowed);
1705                         storage_sync(gprs->imsi, SETTINGS_STORE,
1706                                         gprs->settings);
1707                 }
1708
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);
1713
1714                 if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_BOOLEAN)
1715                         return __ofono_error_invalid_args(msg);
1716
1717                 dbus_message_iter_get_basic(&var, &value);
1718
1719                 if (gprs->powered == (ofono_bool_t) value)
1720                         return dbus_message_new_method_return(msg);
1721
1722                 gprs->powered = value;
1723
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,
1728                                         gprs->settings);
1729                 }
1730
1731                 gprs_netreg_update(gprs);
1732         } else {
1733                 return __ofono_error_invalid_args(msg);
1734         }
1735
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);
1740
1741         return dbus_message_new_method_return(msg);
1742 }
1743
1744 static void write_context_settings(struct ofono_gprs *gprs,
1745                                         struct pri_context *context)
1746 {
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));
1759
1760         if (context->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
1761                 g_key_file_set_string(gprs->settings, context->key,
1762                                         "MessageProxy",
1763                                         context->message_proxy);
1764                 g_key_file_set_string(gprs->settings, context->key,
1765                                         "MessageCenter",
1766                                         context->message_center);
1767         }
1768 }
1769
1770 static struct pri_context *add_context(struct ofono_gprs *gprs,
1771                                         const char *name,
1772                                         enum ofono_gprs_context_type type)
1773 {
1774         unsigned int id;
1775         struct pri_context *context;
1776
1777         if (gprs->last_context_id)
1778                 id = idmap_alloc_next(gprs->pid_map, gprs->last_context_id);
1779         else
1780                 id = idmap_alloc(gprs->pid_map);
1781
1782         if (id > idmap_get_max(gprs->pid_map))
1783                 return NULL;
1784
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");
1789                 return NULL;
1790         }
1791
1792         context->id = id;
1793
1794         DBG("Registering new context");
1795
1796         if (!context_dbus_register(context)) {
1797                 ofono_error("Unable to register primary context");
1798                 return NULL;
1799         }
1800
1801         gprs->last_context_id = id;
1802
1803         if (gprs->settings) {
1804                 write_context_settings(gprs, context);
1805                 storage_sync(gprs->imsi, SETTINGS_STORE, gprs->settings);
1806         }
1807
1808         gprs->contexts = g_slist_append(gprs->contexts, context);
1809
1810         return context;
1811 }
1812
1813 static DBusMessage *gprs_add_context(DBusConnection *conn,
1814                                         DBusMessage *msg, void *data)
1815 {
1816         struct ofono_gprs *gprs = data;
1817         struct pri_context *context;
1818         const char *typestr;
1819         const char *name;
1820         const char *path;
1821         enum ofono_gprs_context_type type;
1822         DBusMessage *signal;
1823
1824         if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &typestr,
1825                                         DBUS_TYPE_INVALID))
1826                 return __ofono_error_invalid_args(msg);
1827
1828         if (gprs_context_string_to_type(typestr, &type) == FALSE)
1829                 return __ofono_error_invalid_format(msg);
1830
1831         name = gprs_context_default_name(type);
1832         if (name == NULL)
1833                 name = typestr;
1834
1835         context = add_context(gprs, name, type);
1836         if (context == NULL)
1837                 return __ofono_error_failed(msg);
1838
1839         path = context->path;
1840
1841         g_dbus_send_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &path,
1842                                         DBUS_TYPE_INVALID);
1843
1844         path = __ofono_atom_get_path(gprs->atom);
1845         signal = dbus_message_new_signal(path,
1846                                         OFONO_CONNECTION_MANAGER_INTERFACE,
1847                                         "ContextAdded");
1848
1849         if (signal) {
1850                 DBusMessageIter iter;
1851                 DBusMessageIter dict;
1852
1853                 dbus_message_iter_init_append(signal, &iter);
1854
1855                 path = context->path;
1856                 dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
1857                                                 &path);
1858
1859                 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
1860                                         OFONO_PROPERTIES_ARRAY_SIGNATURE,
1861                                         &dict);
1862                 append_context_properties(context, &dict);
1863                 dbus_message_iter_close_container(&iter, &dict);
1864
1865                 g_dbus_send_message(conn, signal);
1866         }
1867
1868         return NULL;
1869 }
1870
1871 static void gprs_deactivate_for_remove(const struct ofono_error *error,
1872                                                 void *data)
1873 {
1874         struct pri_context *ctx = data;
1875         struct ofono_gprs *gprs = ctx->gprs;
1876         DBusConnection *conn = ofono_dbus_get_connection();
1877         char *path;
1878         const char *atompath;
1879         dbus_bool_t value;
1880
1881         if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
1882                 DBG("Removing context failed with error: %s",
1883                                 telephony_error_to_str(error));
1884
1885                 __ofono_dbus_pending_reply(&gprs->pending,
1886                                         __ofono_error_failed(gprs->pending));
1887                 return;
1888         }
1889
1890         pri_reset_context_settings(ctx);
1891         release_context(ctx);
1892
1893         value = FALSE;
1894         ofono_dbus_signal_property_changed(conn, ctx->path,
1895                                         OFONO_CONNECTION_CONTEXT_INTERFACE,
1896                                         "Active", DBUS_TYPE_BOOLEAN, &value);
1897
1898         if (gprs->settings) {
1899                 g_key_file_remove_group(gprs->settings, ctx->key, NULL);
1900                 storage_sync(gprs->imsi, SETTINGS_STORE, gprs->settings);
1901         }
1902
1903         /* Make a backup copy of path for signal emission below */
1904         path = g_strdup(ctx->path);
1905
1906         context_dbus_unregister(ctx);
1907         gprs->contexts = g_slist_remove(gprs->contexts, ctx);
1908
1909         __ofono_dbus_pending_reply(&gprs->pending,
1910                                 dbus_message_new_method_return(gprs->pending));
1911
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,
1915                                 DBUS_TYPE_INVALID);
1916         g_free(path);
1917 }
1918
1919 static DBusMessage *gprs_remove_context(DBusConnection *conn,
1920                                         DBusMessage *msg, void *data)
1921 {
1922         struct ofono_gprs *gprs = data;
1923         struct pri_context *ctx;
1924         const char *path;
1925         const char *atompath;
1926
1927         if (gprs->pending)
1928                 return __ofono_error_busy(msg);
1929
1930         if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
1931                                         DBUS_TYPE_INVALID))
1932                 return __ofono_error_invalid_args(msg);
1933
1934         if (path[0] == '\0')
1935                 return __ofono_error_invalid_format(msg);
1936
1937         ctx = gprs_context_by_path(gprs, path);
1938         if (ctx == NULL)
1939                 return __ofono_error_not_found(msg);
1940
1941         if (ctx->active) {
1942                 struct ofono_gprs_context *gc = ctx->context_driver;
1943
1944                 /* This context is already being messed with */
1945                 if (ctx->pending)
1946                         return __ofono_error_busy(msg);
1947
1948                 gprs->pending = dbus_message_ref(msg);
1949                 gc->driver->deactivate_primary(gc, ctx->context.cid,
1950                                         gprs_deactivate_for_remove, ctx);
1951                 return NULL;
1952         }
1953
1954         if (gprs->settings) {
1955                 g_key_file_remove_group(gprs->settings, ctx->key, NULL);
1956                 storage_sync(gprs->imsi, SETTINGS_STORE, gprs->settings);
1957         }
1958
1959         DBG("Unregistering context: %s", ctx->path);
1960         context_dbus_unregister(ctx);
1961         gprs->contexts = g_slist_remove(gprs->contexts, ctx);
1962
1963         g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1964
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,
1968                                 DBUS_TYPE_INVALID);
1969
1970         return NULL;
1971 }
1972
1973 static void gprs_deactivate_for_all(const struct ofono_error *error,
1974                                         void *data)
1975 {
1976         struct pri_context *ctx = data;
1977         struct ofono_gprs *gprs = ctx->gprs;
1978         DBusConnection *conn;
1979         dbus_bool_t value;
1980
1981         if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
1982                 __ofono_dbus_pending_reply(&gprs->pending,
1983                                         __ofono_error_failed(gprs->pending));
1984                 return;
1985         }
1986
1987         pri_reset_context_settings(ctx);
1988         release_context(ctx);
1989
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);
1995
1996         gprs_deactivate_next(gprs);
1997 }
1998
1999 static void gprs_deactivate_next(struct ofono_gprs *gprs)
2000 {
2001         GSList *l;
2002         struct pri_context *ctx;
2003         struct ofono_gprs_context *gc;
2004
2005         for (l = gprs->contexts; l; l = l->next) {
2006                 ctx = l->data;
2007
2008                 if (ctx->active == FALSE)
2009                         continue;
2010
2011                 gc = ctx->context_driver;
2012                 gc->driver->deactivate_primary(gc, ctx->context.cid,
2013                                         gprs_deactivate_for_all, ctx);
2014
2015                 return;
2016         }
2017
2018         __ofono_dbus_pending_reply(&gprs->pending,
2019                                 dbus_message_new_method_return(gprs->pending));
2020 }
2021
2022 static DBusMessage *gprs_deactivate_all(DBusConnection *conn,
2023                                         DBusMessage *msg, void *data)
2024 {
2025         struct ofono_gprs *gprs = data;
2026         GSList *l;
2027         struct pri_context *ctx;
2028
2029         if (gprs->pending)
2030                 return __ofono_error_busy(msg);
2031
2032         if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INVALID))
2033                 return __ofono_error_invalid_args(msg);
2034
2035         for (l = gprs->contexts; l; l = l->next) {
2036                 ctx = l->data;
2037
2038                 if (ctx->pending)
2039                         return __ofono_error_busy(msg);
2040         }
2041
2042         gprs->pending = dbus_message_ref(msg);
2043
2044         gprs_deactivate_next(gprs);
2045
2046         return NULL;
2047 }
2048
2049 static DBusMessage *gprs_get_contexts(DBusConnection *conn,
2050                                         DBusMessage *msg, void *data)
2051 {
2052         struct ofono_gprs *gprs = data;
2053         DBusMessage *reply;
2054         DBusMessageIter iter;
2055         DBusMessageIter array;
2056         DBusMessageIter entry, dict;
2057         const char *path;
2058         GSList *l;
2059         struct pri_context *ctx;
2060
2061         reply = dbus_message_new_method_return(msg);
2062         if (reply == NULL)
2063                 return NULL;
2064
2065         dbus_message_iter_init_append(reply, &iter);
2066
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,
2076                                         &array);
2077
2078         for (l = gprs->contexts; l; l = l->next) {
2079                 ctx = l->data;
2080
2081                 path = ctx->path;
2082
2083                 dbus_message_iter_open_container(&array, DBUS_TYPE_STRUCT,
2084                                                         NULL, &entry);
2085                 dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
2086                                                 &path);
2087                 dbus_message_iter_open_container(&entry, DBUS_TYPE_ARRAY,
2088                                         OFONO_PROPERTIES_ARRAY_SIGNATURE,
2089                                         &dict);
2090
2091                 append_context_properties(ctx, &dict);
2092                 dbus_message_iter_close_container(&entry, &dict);
2093                 dbus_message_iter_close_container(&array, &entry);
2094         }
2095
2096         dbus_message_iter_close_container(&iter, &array);
2097
2098         return reply;
2099 }
2100
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) },
2120         { }
2121 };
2122
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" })) },
2129         { }
2130 };
2131
2132 void ofono_gprs_detached_notify(struct ofono_gprs *gprs)
2133 {
2134         DBG("%s", __ofono_atom_get_path(gprs->atom));
2135
2136         gprs->driver_attached = FALSE;
2137         gprs_attached_update(gprs);
2138
2139         /*
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.
2143          */
2144 }
2145
2146 void ofono_gprs_status_notify(struct ofono_gprs *gprs, int status)
2147 {
2148         DBG("%s status %d", __ofono_atom_get_path(gprs->atom), status);
2149
2150         gprs->status = status;
2151
2152         if (status != NETWORK_REGISTRATION_STATUS_REGISTERED &&
2153                         status != NETWORK_REGISTRATION_STATUS_ROAMING) {
2154                 gprs_attached_update(gprs);
2155                 return;
2156         }
2157
2158         /*
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
2162          */
2163         if (gprs->flags & GPRS_FLAG_ATTACHING)
2164                 return;
2165
2166         /* We registered without being powered */
2167         if (gprs->powered == FALSE)
2168                 goto detach;
2169
2170         if (gprs->roaming_allowed == FALSE &&
2171                         status == NETWORK_REGISTRATION_STATUS_ROAMING)
2172                 goto detach;
2173
2174         gprs->driver_attached = TRUE;
2175         gprs_attached_update(gprs);
2176
2177         return;
2178
2179 detach:
2180         gprs->flags |= GPRS_FLAG_ATTACHING;
2181         gprs->driver->set_attached(gprs, FALSE, gprs_attach_callback, gprs);
2182 }
2183
2184 void ofono_gprs_set_cid_range(struct ofono_gprs *gprs,
2185                                 unsigned int min, unsigned int max)
2186 {
2187         if (gprs == NULL)
2188                 return;
2189
2190         if (gprs->cid_map)
2191                 idmap_free(gprs->cid_map);
2192
2193         gprs->cid_map = idmap_new_from_range(min, max);
2194 }
2195
2196 static void gprs_context_unregister(struct ofono_atom *atom)
2197 {
2198         struct ofono_gprs_context *gc = __ofono_atom_get_data(atom);
2199         DBusConnection *conn = ofono_dbus_get_connection();
2200         GSList *l;
2201         struct pri_context *ctx;
2202         dbus_bool_t value;
2203
2204         DBG("%p, %p", gc, gc->gprs);
2205
2206         if (gc->gprs == NULL)
2207                 goto done;
2208
2209         for (l = gc->gprs->contexts; l; l = l->next) {
2210                 ctx = l->data;
2211
2212                 if (ctx->context_driver != gc)
2213                         continue;
2214
2215                 if (ctx->pending != NULL)
2216                         __ofono_dbus_pending_reply(&ctx->pending,
2217                                         __ofono_error_failed(ctx->pending));
2218
2219                 if (ctx->active == FALSE)
2220                         break;
2221
2222                 pri_reset_context_settings(ctx);
2223                 release_context(ctx);
2224
2225                 value = FALSE;
2226                 ofono_dbus_signal_property_changed(conn, ctx->path,
2227                                         OFONO_CONNECTION_CONTEXT_INTERFACE,
2228                                         "Active", DBUS_TYPE_BOOLEAN, &value);
2229         }
2230
2231         gc->gprs->context_drivers = g_slist_remove(gc->gprs->context_drivers,
2232                                                         gc);
2233         gc->gprs = NULL;
2234
2235 done:
2236         if (gc->settings) {
2237                 context_settings_free(gc->settings);
2238                 g_free(gc->settings);
2239                 gc->settings = NULL;
2240         }
2241 }
2242
2243 void ofono_gprs_add_context(struct ofono_gprs *gprs,
2244                                 struct ofono_gprs_context *gc)
2245 {
2246         if (gc->driver == NULL)
2247                 return;
2248
2249         gc->gprs = gprs;
2250         gc->settings = g_new0(struct context_settings, 1);
2251
2252         gprs->context_drivers = g_slist_append(gprs->context_drivers, gc);
2253         __ofono_atom_register(gc->atom, gprs_context_unregister);
2254 }
2255
2256 void ofono_gprs_bearer_notify(struct ofono_gprs *gprs, int bearer)
2257 {
2258         DBusConnection *conn = ofono_dbus_get_connection();
2259         const char *path;
2260         const char *value;
2261
2262         if (gprs->bearer == bearer)
2263                 return;
2264
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_MANAGER_INTERFACE,
2270                                         "Bearer", DBUS_TYPE_STRING, &value);
2271 }
2272
2273 void ofono_gprs_context_deactivated(struct ofono_gprs_context *gc,
2274                                         unsigned int cid)
2275 {
2276         DBusConnection *conn = ofono_dbus_get_connection();
2277         GSList *l;
2278         struct pri_context *ctx;
2279         dbus_bool_t value;
2280
2281         if (gc->gprs == NULL)
2282                 return;
2283
2284         for (l = gc->gprs->contexts; l; l = l->next) {
2285                 ctx = l->data;
2286
2287                 if (ctx->context.cid != cid)
2288                         continue;
2289
2290                 if (ctx->active == FALSE)
2291                         break;
2292
2293                 pri_reset_context_settings(ctx);
2294                 release_context(ctx);
2295
2296                 value = FALSE;
2297                 ofono_dbus_signal_property_changed(conn, ctx->path,
2298                                         OFONO_CONNECTION_CONTEXT_INTERFACE,
2299                                         "Active", DBUS_TYPE_BOOLEAN, &value);
2300         }
2301
2302         /*
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.
2306          */
2307         if (gc->gprs->flags & GPRS_FLAG_ATTACHED_UPDATE) {
2308                 gc->gprs->flags &= ~GPRS_FLAG_ATTACHED_UPDATE;
2309                 gprs_attached_update(gc->gprs);
2310         }
2311 }
2312
2313 int ofono_gprs_context_driver_register(
2314                                 const struct ofono_gprs_context_driver *d)
2315 {
2316         DBG("driver: %p, name: %s", d, d->name);
2317
2318         if (d->probe == NULL)
2319                 return -EINVAL;
2320
2321         g_context_drivers = g_slist_prepend(g_context_drivers, (void *) d);
2322
2323         return 0;
2324 }
2325
2326 void ofono_gprs_context_driver_unregister(
2327                                 const struct ofono_gprs_context_driver *d)
2328 {
2329         DBG("driver: %p, name: %s", d, d->name);
2330
2331         g_context_drivers = g_slist_remove(g_context_drivers, (void *) d);
2332 }
2333
2334 static void gprs_context_remove(struct ofono_atom *atom)
2335 {
2336         struct ofono_gprs_context *gc = __ofono_atom_get_data(atom);
2337
2338         DBG("atom: %p", atom);
2339
2340         if (gc == NULL)
2341                 return;
2342
2343         if (gc->driver && gc->driver->remove)
2344                 gc->driver->remove(gc);
2345
2346         g_free(gc);
2347 }
2348
2349 struct ofono_gprs_context *ofono_gprs_context_create(struct ofono_modem *modem,
2350                                                 unsigned int vendor,
2351                                                 const char *driver, void *data)
2352 {
2353         struct ofono_gprs_context *gc;
2354         GSList *l;
2355
2356         if (driver == NULL)
2357                 return NULL;
2358
2359         gc = g_try_new0(struct ofono_gprs_context, 1);
2360         if (gc == NULL)
2361                 return NULL;
2362
2363         gc->type = OFONO_GPRS_CONTEXT_TYPE_ANY;
2364
2365         gc->atom = __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_GPRS_CONTEXT,
2366                                                 gprs_context_remove, gc);
2367
2368         for (l = g_context_drivers; l; l = l->next) {
2369                 const struct ofono_gprs_context_driver *drv = l->data;
2370
2371                 if (g_strcmp0(drv->name, driver))
2372                         continue;
2373
2374                 if (drv->probe(gc, vendor, data) < 0)
2375                         continue;
2376
2377                 gc->driver = drv;
2378                 break;
2379         }
2380
2381         return gc;
2382 }
2383
2384 void ofono_gprs_context_remove(struct ofono_gprs_context *gc)
2385 {
2386         if (gc == NULL)
2387                 return;
2388
2389         __ofono_atom_free(gc->atom);
2390 }
2391
2392 void ofono_gprs_context_set_data(struct ofono_gprs_context *gc, void *data)
2393 {
2394         gc->driver_data = data;
2395 }
2396
2397 void *ofono_gprs_context_get_data(struct ofono_gprs_context *gc)
2398 {
2399         return gc->driver_data;
2400 }
2401
2402 struct ofono_modem *ofono_gprs_context_get_modem(struct ofono_gprs_context *gc)
2403 {
2404         return __ofono_atom_get_modem(gc->atom);
2405 }
2406
2407 void ofono_gprs_context_set_type(struct ofono_gprs_context *gc,
2408                                         enum ofono_gprs_context_type type)
2409 {
2410         DBG("type %d", type);
2411
2412         gc->type = type;
2413 }
2414
2415 void ofono_gprs_context_set_interface(struct ofono_gprs_context *gc,
2416                                         const char *interface)
2417 {
2418         struct context_settings *settings = gc->settings;
2419
2420         g_free(settings->interface);
2421         settings->interface = g_strdup(interface);
2422 }
2423
2424 void ofono_gprs_context_set_ipv4_address(struct ofono_gprs_context *gc,
2425                                                 const char *address,
2426                                                 ofono_bool_t static_ip)
2427 {
2428         struct context_settings *settings = gc->settings;
2429
2430         if (settings->ipv4 == NULL)
2431                 return;
2432
2433         g_free(settings->ipv4->ip);
2434         settings->ipv4->ip = g_strdup(address);
2435         settings->ipv4->static_ip = static_ip;
2436 }
2437
2438 void ofono_gprs_context_set_ipv4_netmask(struct ofono_gprs_context *gc,
2439                                                 const char *netmask)
2440 {
2441         struct context_settings *settings = gc->settings;
2442
2443         if (settings->ipv4 == NULL)
2444                 return;
2445
2446         g_free(settings->ipv4->netmask);
2447         settings->ipv4->netmask = g_strdup(netmask);
2448 }
2449
2450 void ofono_gprs_context_set_ipv4_gateway(struct ofono_gprs_context *gc,
2451                                                 const char *gateway)
2452 {
2453         struct context_settings *settings = gc->settings;
2454
2455         if (settings->ipv4 == NULL)
2456                 return;
2457
2458         g_free(settings->ipv4->gateway);
2459         settings->ipv4->gateway = g_strdup(gateway);
2460 }
2461
2462 void ofono_gprs_context_set_ipv4_dns_servers(struct ofono_gprs_context *gc,
2463                                                 const char **dns)
2464 {
2465         struct context_settings *settings = gc->settings;
2466
2467         if (settings->ipv4 == NULL)
2468                 return;
2469
2470         g_strfreev(settings->ipv4->dns);
2471         settings->ipv4->dns = g_strdupv((char **) dns);
2472 }
2473
2474 void ofono_gprs_context_set_ipv6_address(struct ofono_gprs_context *gc,
2475                                                 const char *address)
2476 {
2477         struct context_settings *settings = gc->settings;
2478
2479         if (settings->ipv6 == NULL)
2480                 return;
2481
2482         g_free(settings->ipv6->ip);
2483         settings->ipv6->ip = g_strdup(address);
2484 }
2485
2486 void ofono_gprs_context_set_ipv6_prefix_length(struct ofono_gprs_context *gc,
2487                                                 unsigned char length)
2488 {
2489         struct context_settings *settings = gc->settings;
2490
2491         if (settings->ipv6 == NULL)
2492                 return;
2493
2494         settings->ipv6->prefix_len = length;
2495 }
2496
2497 void ofono_gprs_context_set_ipv6_gateway(struct ofono_gprs_context *gc,
2498                                                 const char *gateway)
2499 {
2500         struct context_settings *settings = gc->settings;
2501
2502         if (settings->ipv6 == NULL)
2503                 return;
2504
2505         g_free(settings->ipv6->gateway);
2506         settings->ipv6->gateway = g_strdup(gateway);
2507 }
2508
2509 void ofono_gprs_context_set_ipv6_dns_servers(struct ofono_gprs_context *gc,
2510                                                 const char **dns)
2511 {
2512         struct context_settings *settings = gc->settings;
2513
2514         if (settings->ipv6 == NULL)
2515                 return;
2516
2517         g_strfreev(settings->ipv6->dns);
2518         settings->ipv6->dns = g_strdupv((char **) dns);
2519 }
2520
2521 int ofono_gprs_driver_register(const struct ofono_gprs_driver *d)
2522 {
2523         DBG("driver: %p, name: %s", d, d->name);
2524
2525         if (d->probe == NULL)
2526                 return -EINVAL;
2527
2528         g_drivers = g_slist_prepend(g_drivers, (void *)d);
2529
2530         return 0;
2531 }
2532
2533 void ofono_gprs_driver_unregister(const struct ofono_gprs_driver *d)
2534 {
2535         DBG("driver: %p, name: %s", d, d->name);
2536
2537         g_drivers = g_slist_remove(g_drivers, (void *)d);
2538 }
2539
2540 static void free_contexts(struct ofono_gprs *gprs)
2541 {
2542         GSList *l;
2543
2544         if (gprs->settings) {
2545                 storage_close(gprs->imsi, SETTINGS_STORE,
2546                                 gprs->settings, TRUE);
2547
2548                 g_free(gprs->imsi);
2549                 gprs->imsi = NULL;
2550                 gprs->settings = NULL;
2551         }
2552
2553         for (l = gprs->contexts; l; l = l->next) {
2554                 struct pri_context *context = l->data;
2555
2556                 context_dbus_unregister(context);
2557         }
2558
2559         g_slist_free(gprs->contexts);
2560 }
2561
2562 static void gprs_unregister(struct ofono_atom *atom)
2563 {
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);
2568
2569         DBG("%p", gprs);
2570
2571         free_contexts(gprs);
2572
2573         if (gprs->cid_map) {
2574                 idmap_free(gprs->cid_map);
2575                 gprs->cid_map = NULL;
2576         }
2577
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;
2583                 }
2584
2585                 __ofono_modem_remove_atom_watch(modem, gprs->netreg_watch);
2586                 gprs->netreg_watch = 0;
2587                 gprs->netreg = NULL;
2588         }
2589
2590         if (gprs->spn_watch) {
2591                 struct ofono_sim *sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM,
2592                                                                 modem);
2593
2594                 ofono_sim_remove_spn_watch(sim, &gprs->spn_watch);
2595         }
2596
2597         ofono_modem_remove_interface(modem,
2598                                         OFONO_CONNECTION_MANAGER_INTERFACE);
2599         g_dbus_unregister_interface(conn, path,
2600                                         OFONO_CONNECTION_MANAGER_INTERFACE);
2601 }
2602
2603 static void gprs_remove(struct ofono_atom *atom)
2604 {
2605         struct ofono_gprs *gprs = __ofono_atom_get_data(atom);
2606         GSList *l;
2607
2608         DBG("atom: %p", atom);
2609
2610         if (gprs == NULL)
2611                 return;
2612
2613         if (gprs->suspend_timeout)
2614                 g_source_remove(gprs->suspend_timeout);
2615
2616         if (gprs->pid_map) {
2617                 idmap_free(gprs->pid_map);
2618                 gprs->pid_map = NULL;
2619         }
2620
2621         for (l = gprs->context_drivers; l; l = l->next) {
2622                 struct ofono_gprs_context *gc = l->data;
2623
2624                 gc->gprs = NULL;
2625         }
2626
2627         g_slist_free(gprs->context_drivers);
2628
2629         if (gprs->driver && gprs->driver->remove)
2630                 gprs->driver->remove(gprs);
2631
2632         g_free(gprs);
2633 }
2634
2635 struct ofono_gprs *ofono_gprs_create(struct ofono_modem *modem,
2636                                         unsigned int vendor,
2637                                         const char *driver, void *data)
2638 {
2639         struct ofono_gprs *gprs;
2640         GSList *l;
2641
2642         if (driver == NULL)
2643                 return NULL;
2644
2645         gprs = g_try_new0(struct ofono_gprs, 1);
2646         if (gprs == NULL)
2647                 return NULL;
2648
2649         gprs->atom = __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_GPRS,
2650                                                 gprs_remove, gprs);
2651
2652         for (l = g_drivers; l; l = l->next) {
2653                 const struct ofono_gprs_driver *drv = l->data;
2654
2655                 if (g_strcmp0(drv->name, driver))
2656                         continue;
2657
2658                 if (drv->probe(gprs, vendor, data) < 0)
2659                         continue;
2660
2661                 gprs->driver = drv;
2662                 break;
2663         }
2664
2665         gprs->status = NETWORK_REGISTRATION_STATUS_UNKNOWN;
2666         gprs->netreg_status = NETWORK_REGISTRATION_STATUS_UNKNOWN;
2667         gprs->pid_map = idmap_new(MAX_CONTEXTS);
2668
2669         return gprs;
2670 }
2671
2672 static void netreg_watch(struct ofono_atom *atom,
2673                                 enum ofono_atom_watch_condition cond,
2674                                 void *data)
2675 {
2676         struct ofono_gprs *gprs = data;
2677
2678         if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
2679                 gprs_netreg_removed(gprs);
2680                 return;
2681         }
2682
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);
2687
2688         gprs_netreg_update(gprs);
2689 }
2690
2691 static gboolean load_context(struct ofono_gprs *gprs, const char *group)
2692 {
2693         char *name = NULL;
2694         char *typestr = NULL;
2695         char *protostr = NULL;
2696         char *username = NULL;
2697         char *password = NULL;
2698         char *apn = 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;
2706         unsigned int id;
2707
2708         if (sscanf(group, "context%d", &id) != 1) {
2709                 if (sscanf(group, "primarycontext%d", &id) != 1)
2710                         goto error;
2711
2712                 legacy = TRUE;
2713         }
2714
2715         if (id < 1 || id > MAX_CONTEXTS)
2716                 goto error;
2717
2718         name = g_key_file_get_string(gprs->settings, group, "Name", NULL);
2719         if (name == NULL)
2720                 goto error;
2721
2722         typestr = g_key_file_get_string(gprs->settings, group, "Type", NULL);
2723         if (typestr == NULL)
2724                 goto error;
2725
2726         if (gprs_context_string_to_type(typestr, &type) == FALSE)
2727                 goto error;
2728
2729         protostr = g_key_file_get_string(gprs->settings, group,
2730                                                         "Protocol", NULL);
2731         if (protostr == NULL)
2732                 protostr = g_strdup("ip");
2733
2734         if (gprs_proto_from_string(protostr, &proto) == FALSE)
2735                 goto error;
2736
2737         username = g_key_file_get_string(gprs->settings, group,
2738                                                 "Username", NULL);
2739         if (username == NULL)
2740                 goto error;
2741
2742         if (strlen(username) > OFONO_GPRS_MAX_USERNAME_LENGTH)
2743                 goto error;
2744
2745         password = g_key_file_get_string(gprs->settings, group,
2746                                                 "Password", NULL);
2747         if (password == NULL)
2748                 goto error;
2749
2750         if (strlen(password) > OFONO_GPRS_MAX_PASSWORD_LENGTH)
2751                 goto error;
2752
2753         apn = g_key_file_get_string(gprs->settings, group,
2754                                         "AccessPointName", NULL);
2755         if (apn == NULL)
2756                 goto error;
2757
2758         if (strlen(apn) > OFONO_GPRS_MAX_APN_LENGTH)
2759                 goto error;
2760
2761         if (type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
2762                 msgproxy = g_key_file_get_string(gprs->settings, group,
2763                                                 "MessageProxy", NULL);
2764
2765                 msgcenter = g_key_file_get_string(gprs->settings, group,
2766                                                 "MessageCenter", NULL);
2767         }
2768
2769         /*
2770          * Accept empty (just created) APNs, but don't allow other
2771          * invalid ones
2772          */
2773         if (apn[0] != '\0' && is_valid_apn(apn) == FALSE)
2774                 goto error;
2775
2776         context = pri_context_create(gprs, name, type);
2777         if (context == NULL)
2778                 goto error;
2779
2780         idmap_take(gprs->pid_map, id);
2781         context->id = id;
2782         strcpy(context->context.username, username);
2783         strcpy(context->context.password, password);
2784         strcpy(context->context.apn, apn);
2785         context->context.proto = proto;
2786
2787         if (msgproxy != NULL)
2788                 strcpy(context->message_proxy, msgproxy);
2789
2790         if (msgcenter != NULL)
2791                 strcpy(context->message_center, msgcenter);
2792
2793         if (context_dbus_register(context) == FALSE)
2794                 goto error;
2795
2796         gprs->last_context_id = id;
2797
2798         gprs->contexts = g_slist_append(gprs->contexts, context);
2799         ret = TRUE;
2800
2801         if (legacy) {
2802                 write_context_settings(gprs, context);
2803                 g_key_file_remove_group(gprs->settings, group, NULL);
2804         }
2805
2806 error:
2807         g_free(name);
2808         g_free(typestr);
2809         g_free(protostr);
2810         g_free(username);
2811         g_free(password);
2812         g_free(apn);
2813         g_free(msgproxy);
2814         g_free(msgcenter);
2815
2816         return ret;
2817 }
2818
2819 static void gprs_load_settings(struct ofono_gprs *gprs, const char *imsi)
2820 {
2821         GError *error;
2822         gboolean legacy = FALSE;
2823         char **groups;
2824         int i;
2825
2826         gprs->settings = storage_open(imsi, SETTINGS_STORE);
2827
2828         if (gprs->settings == NULL)
2829                 return;
2830
2831         gprs->imsi = g_strdup(imsi);
2832
2833         error = NULL;
2834         gprs->powered = g_key_file_get_boolean(gprs->settings, SETTINGS_GROUP,
2835                                                 "Powered", &error);
2836
2837         /*
2838          * If any error occurs, simply switch to defaults.
2839          * Default to Powered = True
2840          * and RoamingAllowed = False
2841          */
2842         if (error) {
2843                 g_error_free(error);
2844                 gprs->powered = TRUE;
2845                 g_key_file_set_boolean(gprs->settings, SETTINGS_GROUP,
2846                                         "Powered", gprs->powered);
2847         }
2848
2849         error = NULL;
2850         gprs->roaming_allowed = g_key_file_get_boolean(gprs->settings,
2851                                                         SETTINGS_GROUP,
2852                                                         "RoamingAllowed",
2853                                                         &error);
2854
2855         if (error) {
2856                 g_error_free(error);
2857                 gprs->roaming_allowed = FALSE;
2858                 g_key_file_set_boolean(gprs->settings, SETTINGS_GROUP,
2859                                         "RoamingAllowed",
2860                                         gprs->roaming_allowed);
2861         }
2862
2863         groups = g_key_file_get_groups(gprs->settings, NULL);
2864
2865         for (i = 0; groups[i]; i++) {
2866                 if (g_str_equal(groups[i], SETTINGS_GROUP))
2867                         continue;
2868
2869                 if (!g_str_has_prefix(groups[i], "context")) {
2870                         if (!g_str_has_prefix(groups[i], "primarycontext"))
2871                                 goto remove;
2872
2873                         legacy = TRUE;
2874                 }
2875
2876                 if (load_context(gprs, groups[i]) == TRUE)
2877                         continue;
2878
2879 remove:
2880                 g_key_file_remove_group(gprs->settings, groups[i], NULL);
2881         }
2882
2883         g_strfreev(groups);
2884
2885         if (legacy)
2886                 storage_sync(imsi, SETTINGS_STORE, gprs->settings);
2887 }
2888
2889 static void provision_context(const struct ofono_gprs_provision_data *ap,
2890                                 struct ofono_gprs *gprs)
2891 {
2892         unsigned int id;
2893         struct pri_context *context = NULL;
2894
2895         /* Sanity check */
2896         if (ap == NULL)
2897                 return;
2898
2899         if (ap->name && strlen(ap->name) > MAX_CONTEXT_NAME_LENGTH)
2900                 return;
2901
2902         if (ap->apn == NULL || strlen(ap->apn) > OFONO_GPRS_MAX_APN_LENGTH)
2903                 return;
2904
2905         if (is_valid_apn(ap->apn) == FALSE)
2906                 return;
2907
2908         if (ap->username &&
2909                         strlen(ap->username) > OFONO_GPRS_MAX_USERNAME_LENGTH)
2910                 return;
2911
2912         if (ap->password &&
2913                         strlen(ap->password) > OFONO_GPRS_MAX_PASSWORD_LENGTH)
2914                 return;
2915
2916         if (ap->message_proxy &&
2917                         strlen(ap->message_proxy) > MAX_MESSAGE_PROXY_LENGTH)
2918                 return;
2919
2920         if (ap->message_center &&
2921                         strlen(ap->message_center) > MAX_MESSAGE_CENTER_LENGTH)
2922                 return;
2923
2924         if (gprs->last_context_id)
2925                 id = idmap_alloc_next(gprs->pid_map, gprs->last_context_id);
2926         else
2927                 id = idmap_alloc(gprs->pid_map);
2928
2929         if (id > idmap_get_max(gprs->pid_map))
2930                 return;
2931
2932         context = pri_context_create(gprs, ap->name, ap->type);
2933         if (context == NULL) {
2934                 idmap_put(gprs->pid_map, id);
2935                 return;
2936         }
2937
2938         context->id = id;
2939
2940         if (ap->username != NULL)
2941                 strcpy(context->context.username, ap->username);
2942
2943         if (ap->password != NULL)
2944                 strcpy(context->context.password, ap->password);
2945
2946         strcpy(context->context.apn, ap->apn);
2947         context->context.proto = ap->proto;
2948
2949         if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
2950                 if (ap->message_proxy != NULL)
2951                         strcpy(context->message_proxy, ap->message_proxy);
2952
2953                 if (ap->message_center != NULL)
2954                         strcpy(context->message_center, ap->message_center);
2955         }
2956
2957         if (context_dbus_register(context) == FALSE)
2958                 return;
2959
2960         gprs->last_context_id = id;
2961
2962         if (gprs->settings) {
2963                 write_context_settings(gprs, context);
2964                 storage_sync(gprs->imsi, SETTINGS_STORE, gprs->settings);
2965         }
2966
2967         gprs->contexts = g_slist_append(gprs->contexts, context);
2968 }
2969
2970 static void provision_contexts(struct ofono_gprs *gprs, const char *mcc,
2971                                 const char *mnc, const char *spn)
2972 {
2973         struct ofono_gprs_provision_data *settings;
2974         int count;
2975         int i;
2976
2977         if (__ofono_gprs_provision_get_settings(mcc, mnc, spn,
2978                                                 &settings, &count) == FALSE) {
2979                 ofono_warn("Provisioning failed");
2980                 return;
2981         }
2982
2983         for (i = 0; i < count; i++)
2984                 provision_context(&settings[i], gprs);
2985
2986         __ofono_gprs_provision_free_settings(settings, count);
2987 }
2988
2989 static void ofono_gprs_finish_register(struct ofono_gprs *gprs)
2990 {
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);
2994
2995         if (gprs->contexts == NULL) /* Automatic provisioning failed */
2996                 add_context(gprs, NULL, OFONO_GPRS_CONTEXT_TYPE_INTERNET);
2997
2998         if (!g_dbus_register_interface(conn, path,
2999                                         OFONO_CONNECTION_MANAGER_INTERFACE,
3000                                         manager_methods, manager_signals, NULL,
3001                                         gprs, NULL)) {
3002                 ofono_error("Could not create %s interface",
3003                                 OFONO_CONNECTION_MANAGER_INTERFACE);
3004
3005                 free_contexts(gprs);
3006                 return;
3007         }
3008
3009         ofono_modem_add_interface(modem,
3010                                 OFONO_CONNECTION_MANAGER_INTERFACE);
3011
3012         gprs->netreg_watch = __ofono_modem_add_atom_watch(modem,
3013                                         OFONO_ATOM_TYPE_NETREG,
3014                                         netreg_watch, gprs, NULL);
3015
3016         __ofono_atom_register(gprs->atom, gprs_unregister);
3017 }
3018
3019 static void spn_read_cb(const char *spn, const char *dc, void *data)
3020 {
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);
3024
3025         provision_contexts(gprs, ofono_sim_get_mcc(sim),
3026                                         ofono_sim_get_mnc(sim), spn);
3027
3028         ofono_sim_remove_spn_watch(sim, &gprs->spn_watch);
3029
3030         ofono_gprs_finish_register(gprs);
3031 }
3032
3033 void ofono_gprs_register(struct ofono_gprs *gprs)
3034 {
3035         struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
3036         struct ofono_sim *sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem);
3037
3038         if (sim == NULL)
3039                 goto finish;
3040
3041         gprs_load_settings(gprs, ofono_sim_get_imsi(sim));
3042
3043         if (gprs->contexts)
3044                 goto finish;
3045
3046         ofono_sim_add_spn_watch(sim, &gprs->spn_watch, spn_read_cb, gprs, NULL);
3047         return;
3048
3049 finish:
3050         ofono_gprs_finish_register(gprs);
3051 }
3052
3053 void ofono_gprs_remove(struct ofono_gprs *gprs)
3054 {
3055         __ofono_atom_free(gprs->atom);
3056 }
3057
3058 void ofono_gprs_set_data(struct ofono_gprs *gprs, void *data)
3059 {
3060         gprs->driver_data = data;
3061 }
3062
3063 void *ofono_gprs_get_data(struct ofono_gprs *gprs)
3064 {
3065         return gprs->driver_data;
3066 }