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