~indicator-network-developers/connman/head.packaging

« back to all changes in this revision

Viewing changes to src/provider.c

  • Committer: Antti Kaijanmäki
  • Date: 2011-11-27 16:50:21 UTC
  • mfrom: (2395.1.8 merge-head)
  • Revision ID: antti.kaijanmaki@canonical.com-20111127165021-p6lh1j494wisde77
* Merge from upstream
  * bump upstream version
* refresh distro patches
  * 08-remove-internal-backtrace-hand.patch: drop for rewrite

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include <config.h>
24
24
#endif
25
25
 
 
26
#include <errno.h>
26
27
#include <stdio.h>
27
28
#include <string.h>
28
29
#include <stdlib.h>
44
45
};
45
46
 
46
47
struct connman_provider {
47
 
        struct connman_element element;
 
48
        int refcount;
48
49
        struct connman_service *vpn_service;
 
50
        int index;
49
51
        char *identifier;
50
52
        char *name;
51
53
        char *type;
55
57
        GHashTable *routes;
56
58
        struct connman_provider_driver *driver;
57
59
        void *driver_data;
 
60
        GHashTable *setting_strings;
58
61
};
59
62
 
60
63
void __connman_provider_append_properties(struct connman_provider *provider,
73
76
                                                 &provider->type);
74
77
}
75
78
 
 
79
static int connman_provider_load(struct connman_provider *provider)
 
80
{
 
81
        gsize idx = 0;
 
82
        GKeyFile *keyfile;
 
83
        gchar **settings;
 
84
        gchar *key, *value;
 
85
        gsize length;
 
86
 
 
87
        DBG("provider %p", provider);
 
88
 
 
89
        keyfile = __connman_storage_load_provider(provider->identifier);
 
90
        if (keyfile == NULL)
 
91
                return -ENOENT;
 
92
 
 
93
        settings = g_key_file_get_keys(keyfile, provider->identifier, &length,
 
94
                                NULL);
 
95
        if (settings == NULL) {
 
96
                g_key_file_free(keyfile);
 
97
                return -ENOENT;
 
98
        }
 
99
 
 
100
        while (idx < length) {
 
101
                key = settings[idx];
 
102
                DBG("found key %s", key);
 
103
                if (key != NULL) {
 
104
                        value = g_key_file_get_string(keyfile,
 
105
                                                provider->identifier,
 
106
                                                key, NULL);
 
107
                        connman_provider_set_string(provider, key, value);
 
108
                        g_free(value);
 
109
                }
 
110
                idx += 1;
 
111
        }
 
112
        g_strfreev(settings);
 
113
 
 
114
        g_key_file_free(keyfile);
 
115
        return 0;
 
116
}
 
117
 
 
118
static int connman_provider_save(struct connman_provider *provider)
 
119
{
 
120
        GKeyFile *keyfile;
 
121
 
 
122
        DBG("provider %p", provider);
 
123
 
 
124
        keyfile = g_key_file_new();
 
125
        if (keyfile == NULL)
 
126
                return -ENOMEM;
 
127
 
 
128
        g_key_file_set_string(keyfile, provider->identifier,
 
129
                        "Name", provider->name);
 
130
        g_key_file_set_string(keyfile, provider->identifier,
 
131
                        "Type", provider->type);
 
132
        g_key_file_set_string(keyfile, provider->identifier,
 
133
                        "Host", provider->host);
 
134
        g_key_file_set_string(keyfile, provider->identifier,
 
135
                        "VPN.Domain", provider->domain);
 
136
 
 
137
        if (provider->driver != NULL && provider->driver->save != NULL)
 
138
                provider->driver->save(provider, keyfile);
 
139
 
 
140
        __connman_storage_save_provider(keyfile, provider->identifier);
 
141
        g_key_file_free(keyfile);
 
142
 
 
143
        return 0;
 
144
}
 
145
 
76
146
static struct connman_provider *connman_provider_lookup(const char *identifier)
77
147
{
78
148
        struct connman_provider *provider = NULL;
82
152
        return provider;
83
153
}
84
154
 
85
 
struct connman_provider *connman_provider_ref(struct connman_provider *provider)
86
 
{
87
 
        DBG("provider %p", provider);
88
 
 
89
 
        if (connman_element_ref(&provider->element) == NULL)
90
 
                return NULL;
91
 
 
92
 
        return provider;
93
 
}
94
 
 
95
 
void connman_provider_unref(struct connman_provider *provider)
96
 
{
97
 
        DBG("provider %p", provider);
98
 
 
99
 
        connman_element_unref(&provider->element);
100
 
}
101
 
 
102
155
static gboolean match_driver(struct connman_provider *provider,
103
156
                                struct connman_provider_driver *driver)
104
157
{
137
190
        return 0;
138
191
}
139
192
 
 
193
static void provider_remove(struct connman_provider *provider)
 
194
{
 
195
        if (provider->driver != NULL) {
 
196
                provider->driver->remove(provider);
 
197
                provider->driver = NULL;
 
198
        }
 
199
}
 
200
 
 
201
static int provider_register(struct connman_provider *provider)
 
202
{
 
203
        connman_provider_load(provider);
 
204
        return provider_probe(provider);
 
205
}
 
206
 
 
207
static void provider_unregister(struct connman_provider *provider)
 
208
{
 
209
        provider_remove(provider);
 
210
}
 
211
 
 
212
struct connman_provider *connman_provider_ref(struct connman_provider *provider)
 
213
{
 
214
        DBG("provider %p refcount %d", provider, provider->refcount + 1);
 
215
 
 
216
        __sync_fetch_and_add(&provider->refcount, 1);
 
217
 
 
218
        return provider;
 
219
}
 
220
 
 
221
static void provider_destruct(struct connman_provider *provider)
 
222
{
 
223
        DBG("provider %p", provider);
 
224
 
 
225
        g_free(provider->name);
 
226
        g_free(provider->type);
 
227
        g_free(provider->host);
 
228
        g_free(provider->domain);
 
229
        g_free(provider->identifier);
 
230
        g_hash_table_destroy(provider->routes);
 
231
        g_hash_table_destroy(provider->setting_strings);
 
232
}
 
233
 
 
234
void connman_provider_unref(struct connman_provider *provider)
 
235
{
 
236
        DBG("provider %p refcount %d", provider, provider->refcount - 1);
 
237
 
 
238
        if (__sync_fetch_and_sub(&provider->refcount, 1) != 1)
 
239
                return;
 
240
 
 
241
        provider_remove(provider);
 
242
 
 
243
        provider_destruct(provider);
 
244
}
 
245
 
140
246
static int provider_indicate_state(struct connman_provider *provider,
141
247
                                        enum connman_service_state state)
142
248
{
143
249
        DBG("state %d", state);
144
250
 
145
 
        __connman_service_indicate_state(provider->vpn_service, state,
 
251
        __connman_service_ipconfig_indicate_state(provider->vpn_service, state,
146
252
                                        CONNMAN_IPCONFIG_TYPE_IPV4);
147
253
 
148
 
        return __connman_service_indicate_state(provider->vpn_service, state,
149
 
                                        CONNMAN_IPCONFIG_TYPE_IPV6);
 
254
        return __connman_service_ipconfig_indicate_state(provider->vpn_service,
 
255
                                        state, CONNMAN_IPCONFIG_TYPE_IPV6);
150
256
}
151
257
 
152
258
int __connman_provider_disconnect(struct connman_provider *provider)
218
324
 
219
325
                if (g_strcmp0(srv_path, path) == 0) {
220
326
                        DBG("Removing VPN %s", provider->identifier);
 
327
 
 
328
                        provider_unregister(provider);
221
329
                        g_hash_table_remove(provider_hash,
222
330
                                                provider->identifier);
223
331
                        return 0;
232
340
{
233
341
        struct connman_route *route = value;
234
342
        struct connman_provider *provider = user_data;
235
 
        int index = provider->element.index;
 
343
        int index = provider->index;
236
344
 
237
345
        if (route->family == AF_INET6) {
238
346
                unsigned char prefix_len = atoi(route->netmask);
319
427
                                        enum connman_provider_error error)
320
428
{
321
429
        enum connman_service_error service_error;
 
430
        const char *path;
 
431
        int ret;
322
432
 
323
433
        switch (error) {
324
434
        case CONNMAN_PROVIDER_ERROR_LOGIN_FAILED:
335
445
                break;
336
446
        }
337
447
 
338
 
        return __connman_service_indicate_error(provider->vpn_service,
 
448
        ret = __connman_service_indicate_error(provider->vpn_service,
339
449
                                                        service_error);
 
450
        path = __connman_service_get_path(provider->vpn_service);
 
451
        __connman_provider_remove(path);
 
452
 
 
453
        return ret;
340
454
}
341
455
 
342
456
static void unregister_provider(gpointer data)
349
463
        provider->vpn_service = NULL;
350
464
        __connman_service_put(service);
351
465
 
352
 
        connman_element_unregister(&provider->element);
353
466
        connman_provider_unref(provider);
354
467
}
355
468
 
356
 
static void provider_destruct(struct connman_element *element)
357
 
{
358
 
        struct connman_provider *provider = element->private;
359
 
 
360
 
        DBG("provider %p", provider);
361
 
 
362
 
        g_free(provider->name);
363
 
        g_free(provider->type);
364
 
        g_free(provider->domain);
365
 
        g_free(provider->identifier);
366
 
        g_hash_table_destroy(provider->routes);
367
 
}
368
 
 
369
469
static void destroy_route(gpointer user_data)
370
470
{
371
471
        struct connman_route *route = user_data;
380
480
{
381
481
        DBG("provider %p", provider);
382
482
 
383
 
        __connman_element_initialize(&provider->element);
384
 
 
385
 
        provider->element.private = provider;
386
 
        provider->element.destruct = provider_destruct;
387
 
 
 
483
        provider->index = 0;
388
484
        provider->name = NULL;
389
485
        provider->type = NULL;
390
486
        provider->domain = NULL;
391
487
        provider->identifier = NULL;
392
488
        provider->routes = g_hash_table_new_full(g_direct_hash, g_direct_equal,
393
489
                                        NULL, destroy_route);
 
490
        provider->setting_strings = g_hash_table_new_full(g_str_hash, g_str_equal,
 
491
                                                        g_free, g_free);
394
492
}
395
493
 
396
494
static struct connman_provider *connman_provider_new(void)
401
499
        if (provider == NULL)
402
500
                return NULL;
403
501
 
 
502
        provider->refcount = 1;
 
503
 
404
504
        DBG("provider %p", provider);
405
505
        provider_initialize(provider);
406
506
 
425
525
 
426
526
        g_hash_table_insert(provider_hash, provider->identifier, provider);
427
527
 
428
 
        provider->element.name = g_strdup(identifier);
429
 
        connman_element_register(&provider->element, NULL);
 
528
        provider->name = g_strdup(identifier);
430
529
 
431
530
        return provider;
432
531
}
450
549
{
451
550
        struct connman_provider *provider;
452
551
        DBusMessageIter iter, array;
453
 
        const char *type = NULL, *name = NULL, *service_path = NULL;
 
552
        const char *type = NULL, *name = NULL, *service_path;
454
553
        const char *host = NULL, *domain = NULL;
455
554
        char *ident;
456
 
        gboolean created = FALSE;
457
555
        int err;
458
556
 
459
557
        dbus_message_iter_init(msg, &iter);
485
583
                dbus_message_iter_next(&array);
486
584
        }
487
585
 
488
 
        if (host == NULL || domain == NULL) {
489
 
                err = -EINVAL;
490
 
                goto failed;
491
 
        }
 
586
        if (host == NULL || domain == NULL)
 
587
                return -EINVAL;
492
588
 
493
589
        DBG("Type %s name %s", type, name);
494
590
 
495
 
        if (type == NULL || name == NULL) {
496
 
                err = -EOPNOTSUPP;
497
 
                goto failed;
498
 
        }
 
591
        if (type == NULL || name == NULL)
 
592
                return -EOPNOTSUPP;
499
593
 
500
594
        ident = g_strdup_printf("%s_%s", host, domain);
501
595
        provider_dbus_ident(ident);
503
597
        DBG("ident %s", ident);
504
598
 
505
599
        provider = connman_provider_lookup(ident);
506
 
 
507
600
        if (provider == NULL) {
508
 
                created = TRUE;
509
601
                provider = connman_provider_get(ident);
510
 
                if (provider) {
511
 
                        provider->host = g_strdup(host);
512
 
                        provider->domain = g_strdup(domain);
513
 
                        provider->name = g_strdup(name);
514
 
                        provider->type = g_strdup(type);
 
602
                if (provider == NULL) {
 
603
                        DBG("can not create provider");
 
604
                        g_free(ident);
 
605
                        return -EOPNOTSUPP;
515
606
                }
516
 
        }
517
 
 
518
 
        if (provider == NULL) {
519
 
                DBG("can not create provider");
520
 
                err = -EOPNOTSUPP;
521
 
                goto failed;
522
 
        }
 
607
 
 
608
                provider->host = g_strdup(host);
 
609
                provider->domain = g_strdup(domain);
 
610
                g_free(provider->name);
 
611
                provider->name = g_strdup(name);
 
612
                provider->type = g_strdup(type);
 
613
 
 
614
                provider_register(provider);
 
615
        }
 
616
 
523
617
        dbus_message_iter_init(msg, &iter);
524
618
        dbus_message_iter_recurse(&iter, &array);
525
619
 
545
639
 
546
640
        g_free(ident);
547
641
 
548
 
        if (provider == NULL) {
549
 
                err = -EOPNOTSUPP;
550
 
                goto failed;
551
 
        }
552
 
 
553
 
        if (created == TRUE)
554
 
                provider_probe(provider);
555
 
 
556
 
        if (provider->vpn_service == NULL)
 
642
        if (provider->vpn_service == NULL) {
557
643
                provider->vpn_service =
558
644
                        __connman_service_create_from_provider(provider);
559
 
        if (provider->vpn_service == NULL) {
560
 
                err = -EOPNOTSUPP;
561
 
                goto failed;
562
 
        }
563
 
 
564
 
        err = __connman_service_connect(provider->vpn_service);
565
 
        if (err < 0 && err != -EINPROGRESS)
566
 
                goto failed;
567
 
 
 
645
                if (provider->vpn_service == NULL) {
 
646
                        err = -EOPNOTSUPP;
 
647
                        goto unref;
 
648
                }
 
649
 
 
650
                err = __connman_service_connect(provider->vpn_service);
 
651
                if (err < 0 && err != -EINPROGRESS)
 
652
                        goto failed;
 
653
        } else
 
654
                DBG("provider already connected");
 
655
 
 
656
        connman_provider_save(provider);
568
657
        service_path = __connman_service_get_path(provider->vpn_service);
569
658
        g_dbus_send_reply(connection, msg,
570
659
                                DBUS_TYPE_OBJECT_PATH, &service_path,
572
661
        return 0;
573
662
 
574
663
failed:
575
 
        if (provider != NULL && created == TRUE) {
576
 
                DBG("can not connect delete provider");
577
 
                connman_provider_unref(provider);
578
 
 
579
 
                if (provider->vpn_service != NULL) {
580
 
                        __connman_service_put(provider->vpn_service);
581
 
                        provider->vpn_service = NULL;
582
 
                }
583
 
        }
 
664
        __connman_service_put(provider->vpn_service);
 
665
        provider->vpn_service = NULL;
 
666
 
 
667
unref:
 
668
        DBG("can not connect, delete provider");
 
669
 
 
670
        connman_provider_unref(provider);
584
671
 
585
672
        return err;
586
673
}
604
691
        } else if (g_str_equal(key, "Name") == TRUE) {
605
692
                g_free(provider->name);
606
693
                provider->name = g_strdup(value);
607
 
        }
608
 
 
609
 
        return connman_element_set_string(&provider->element, key, value);
 
694
        } else if (g_str_equal(key, "Host") == TRUE) {
 
695
                g_free(provider->host);
 
696
                provider->host = g_strdup(value);
 
697
        } else if (g_str_equal(key, "VPN.Domain") == TRUE) {
 
698
                g_free(provider->domain);
 
699
                provider->domain = g_strdup(value);
 
700
        } else
 
701
                g_hash_table_replace(provider->setting_strings,
 
702
                                g_strdup(key), g_strdup(value));
 
703
        return 0;
610
704
}
611
705
 
612
706
const char *connman_provider_get_string(struct connman_provider *provider,
618
712
                return provider->type;
619
713
        else if (g_str_equal(key, "Name") == TRUE)
620
714
                return provider->name;
 
715
        else if (g_str_equal(key, "Host") == TRUE)
 
716
                return provider->host;
 
717
        else if (g_str_equal(key, "VPN.Domain") == TRUE)
 
718
                return provider->domain;
621
719
 
622
 
        return connman_element_get_string(&provider->element, key);
 
720
        return g_hash_table_lookup(provider->setting_strings, key);
623
721
}
624
722
 
625
723
void *connman_provider_get_data(struct connman_provider *provider)
674
772
        __connman_ipconfig_set_index(ipconfig, index);
675
773
 
676
774
done:
677
 
        provider->element.index = index;
 
775
        provider->index = index;
678
776
}
679
777
 
680
778
int connman_provider_get_index(struct connman_provider *provider)
681
779
{
682
 
        return provider->element.index;
 
780
        return provider->index;
683
781
}
684
782
 
685
783
int connman_provider_set_ipaddress(struct connman_provider *provider,
736
834
 
737
835
        __connman_service_nameserver_clear(provider->vpn_service);
738
836
 
739
 
        if (nameservers != NULL)
740
 
                nameservers_array = g_strsplit(nameservers, " ", 0);
 
837
        if (nameservers == NULL)
 
838
                return 0;
 
839
 
 
840
        nameservers_array = g_strsplit(nameservers, " ", 0);
741
841
 
742
842
        for (i = 0; nameservers_array[i] != NULL; i++) {
743
843
                __connman_service_nameserver_append(provider->vpn_service,
856
956
 
857
957
const char *connman_provider_get_driver_name(struct connman_provider *provider)
858
958
{
 
959
        if (provider->driver == NULL)
 
960
                return NULL;
 
961
 
859
962
        return provider->driver->name;
860
963
}
861
964
 
 
965
const char *connman_provider_get_save_group(struct connman_provider *provider)
 
966
{
 
967
        return provider->identifier;
 
968
}
 
969
 
862
970
static gint compare_priority(gconstpointer a, gconstpointer b)
863
971
{
864
972
        return 0;
888
996
        driver_list = g_slist_remove(driver_list, driver);
889
997
}
890
998
 
891
 
static void provider_remove(gpointer key, gpointer value,
 
999
static void provider_remove_all(gpointer key, gpointer value,
892
1000
                                                gpointer user_data)
893
1001
{
894
1002
        struct connman_provider *provider = value;
895
1003
 
896
 
        g_hash_table_remove(provider_hash, provider->identifier);
 
1004
        __connman_provider_remove(provider->identifier);
897
1005
}
898
1006
 
899
1007
static void provider_offline_mode(connman_bool_t enabled)
901
1009
        DBG("enabled %d", enabled);
902
1010
 
903
1011
        if (enabled == TRUE)
904
 
                g_hash_table_foreach(provider_hash, provider_remove, NULL);
 
1012
                g_hash_table_foreach(provider_hash, provider_remove_all, NULL);
905
1013
 
906
1014
}
907
1015