090b7e7322094704fead21e9993c4687ede3b541
[platform/upstream/connman.git] / src / network.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2010  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 <errno.h>
27 #include <string.h>
28
29 #include "connman.h"
30
31 static GSList *network_list = NULL;
32 static GSList *driver_list = NULL;
33
34 struct connman_network {
35         int refcount;
36         enum connman_network_type type;
37         connman_bool_t available;
38         connman_bool_t connected;
39         connman_bool_t roaming;
40         connman_uint8_t strength;
41         connman_uint16_t frequency;
42         char *identifier;
43         char *name;
44         char *node;
45         char *group;
46         char *path;
47         int index;
48
49         struct connman_network_driver *driver;
50         void *driver_data;
51
52         connman_bool_t connecting;
53         connman_bool_t associating;
54
55         struct connman_device *device;
56
57         struct {
58                 void *ssid;
59                 int ssid_len;
60                 char *mode;
61                 unsigned short channel;
62                 char *security;
63                 char *passphrase;
64                 char *agent_passphrase;
65                 char *eap;
66                 char *identity;
67                 char *agent_identity;
68                 char *ca_cert_path;
69                 char *client_cert_path;
70                 char *private_key_path;
71                 char *private_key_passphrase;
72                 char *phase2_auth;
73                 connman_bool_t wps;
74                 connman_bool_t use_wps;
75                 char *pin_wps;
76         } wifi;
77
78         struct {
79                 char *nsp_name;
80                 int nsp_name_len;
81         } wimax;
82 };
83
84 static const char *type2string(enum connman_network_type type)
85 {
86         switch (type) {
87         case CONNMAN_NETWORK_TYPE_UNKNOWN:
88         case CONNMAN_NETWORK_TYPE_VENDOR:
89                 break;
90         case CONNMAN_NETWORK_TYPE_ETHERNET:
91                 return "ethernet";
92         case CONNMAN_NETWORK_TYPE_WIFI:
93                 return "wifi";
94         case CONNMAN_NETWORK_TYPE_WIMAX:
95                 return "wimax";
96         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
97         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
98                 return "bluetooth";
99         case CONNMAN_NETWORK_TYPE_CELLULAR:
100                 return "cellular";
101         }
102
103         return NULL;
104 }
105
106 connman_bool_t __connman_network_has_driver(struct connman_network *network)
107 {
108         if (network == NULL || network->driver == NULL)
109                 return FALSE;
110
111         return TRUE;
112 }
113
114 static gboolean match_driver(struct connman_network *network,
115                                         struct connman_network_driver *driver)
116 {
117         if (network->type == driver->type ||
118                         driver->type == CONNMAN_NETWORK_TYPE_UNKNOWN)
119                 return TRUE;
120
121         return FALSE;
122 }
123
124 static int network_probe(struct connman_network *network)
125 {
126         GSList *list;
127         struct connman_network_driver *driver = NULL;
128
129         DBG("network %p name %s", network, network->name);
130
131         if (network->driver != NULL)
132                 return -EALREADY;
133
134         for (list = driver_list; list; list = list->next) {
135                 driver = list->data;
136
137                 if (match_driver(network, driver) == FALSE)
138                         continue;
139
140                 DBG("driver %p name %s", driver, driver->name);
141
142                 if (driver->probe(network) == 0)
143                         break;
144
145                 driver = NULL;
146         }
147
148         if (driver == NULL)
149                 return -ENODEV;
150
151         if (network->group == NULL)
152                 return -EINVAL;
153
154         switch (network->type) {
155         case CONNMAN_NETWORK_TYPE_UNKNOWN:
156         case CONNMAN_NETWORK_TYPE_VENDOR:
157                 return 0;
158         case CONNMAN_NETWORK_TYPE_ETHERNET:
159         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
160         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
161         case CONNMAN_NETWORK_TYPE_CELLULAR:
162         case CONNMAN_NETWORK_TYPE_WIFI:
163         case CONNMAN_NETWORK_TYPE_WIMAX:
164                 network->driver = driver;
165                 if (__connman_service_create_from_network(network) == NULL) {
166                         network->driver = NULL;
167                         return -EINVAL;
168                 }
169         }
170
171         return 0;
172 }
173
174 static void network_remove(struct connman_network *network)
175 {
176         DBG("network %p name %s", network, network->name);
177
178         if (network->driver == NULL)
179                 return;
180
181         connman_network_set_connected(network, FALSE);
182
183         switch (network->type) {
184         case CONNMAN_NETWORK_TYPE_UNKNOWN:
185         case CONNMAN_NETWORK_TYPE_VENDOR:
186                 break;
187         case CONNMAN_NETWORK_TYPE_ETHERNET:
188         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
189         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
190         case CONNMAN_NETWORK_TYPE_CELLULAR:
191         case CONNMAN_NETWORK_TYPE_WIFI:
192         case CONNMAN_NETWORK_TYPE_WIMAX:
193                 if (network->group != NULL) {
194                         __connman_service_remove_from_network(network);
195
196                         g_free(network->group);
197                         network->group = NULL;
198                 }
199                 break;
200         }
201
202         if (network->driver->remove)
203                 network->driver->remove(network);
204
205         network->driver = NULL;
206 }
207
208 static void network_change(struct connman_network *network)
209 {
210         DBG("network %p name %s", network, network->name);
211
212         if (network->connected == FALSE)
213                 return;
214
215         connman_device_set_disconnected(network->device, TRUE);
216
217         if (network->driver && network->driver->disconnect) {
218                 network->driver->disconnect(network);
219                 return;
220         }
221
222         network->connected = FALSE;
223 }
224
225 static void probe_driver(struct connman_network_driver *driver)
226 {
227         GSList *list;
228
229         DBG("driver %p name %s", driver, driver->name);
230
231         for (list = network_list; list != NULL; list = list->next) {
232                 struct connman_network *network = list->data;
233
234                 if (network->driver != NULL)
235                         continue;
236
237                 if (driver->type != network->type)
238                         continue;
239
240                 if (driver->probe(network) < 0)
241                         continue;
242
243                 network->driver = driver;
244         }
245 }
246
247 static void remove_driver(struct connman_network_driver *driver)
248 {
249         GSList *list;
250
251         DBG("driver %p name %s", driver, driver->name);
252
253         for (list = network_list; list != NULL; list = list->next) {
254                 struct connman_network *network = list->data;
255
256                 if (network->driver == driver)
257                         network_remove(network);
258         }
259 }
260
261 static gint compare_priority(gconstpointer a, gconstpointer b)
262 {
263         const struct connman_network_driver *driver1 = a;
264         const struct connman_network_driver *driver2 = b;
265
266         return driver2->priority - driver1->priority;
267 }
268
269 /**
270  * connman_network_driver_register:
271  * @driver: network driver definition
272  *
273  * Register a new network driver
274  *
275  * Returns: %0 on success
276  */
277 int connman_network_driver_register(struct connman_network_driver *driver)
278 {
279         GSList *list;
280
281         DBG("driver %p name %s", driver, driver->name);
282
283         for (list = driver_list; list; list = list->next) {
284                 struct connman_network_driver *tmp = list->data;
285
286                 if (tmp->type == driver->type)
287                         return -EALREADY;
288
289         }
290
291         driver_list = g_slist_insert_sorted(driver_list, driver,
292                                                         compare_priority);
293
294         probe_driver(driver);
295
296         return 0;
297 }
298
299 /**
300  * connman_network_driver_unregister:
301  * @driver: network driver definition
302  *
303  * Remove a previously registered network driver
304  */
305 void connman_network_driver_unregister(struct connman_network_driver *driver)
306 {
307         DBG("driver %p name %s", driver, driver->name);
308
309         driver_list = g_slist_remove(driver_list, driver);
310
311         remove_driver(driver);
312 }
313
314 static void network_destruct(struct connman_network *network)
315 {
316         DBG("network %p name %s", network, network->name);
317
318         g_free(network->wifi.ssid);
319         g_free(network->wifi.mode);
320         g_free(network->wifi.security);
321         g_free(network->wifi.passphrase);
322         g_free(network->wifi.agent_passphrase);
323         g_free(network->wifi.eap);
324         g_free(network->wifi.identity);
325         g_free(network->wifi.agent_identity);
326         g_free(network->wifi.ca_cert_path);
327         g_free(network->wifi.client_cert_path);
328         g_free(network->wifi.private_key_path);
329         g_free(network->wifi.private_key_passphrase);
330         g_free(network->wifi.phase2_auth);
331         g_free(network->wifi.pin_wps);
332
333         g_free(network->path);
334         g_free(network->group);
335         g_free(network->node);
336         g_free(network->name);
337         g_free(network->identifier);
338
339         network->device = NULL;
340
341         g_free(network);
342 }
343
344 /**
345  * connman_network_create:
346  * @identifier: network identifier (for example an unqiue name)
347  *
348  * Allocate a new network and assign the #identifier to it.
349  *
350  * Returns: a newly-allocated #connman_network structure
351  */
352 struct connman_network *connman_network_create(const char *identifier,
353                                                 enum connman_network_type type)
354 {
355         struct connman_network *network;
356         char *ident;
357
358         DBG("identifier %s type %d", identifier, type);
359
360         network = g_try_new0(struct connman_network, 1);
361         if (network == NULL)
362                 return NULL;
363
364         DBG("network %p", network);
365
366         network->refcount = 1;
367
368         ident = g_strdup(identifier);
369
370         if (ident == NULL) {
371                 g_free(network);
372                 return NULL;
373         }
374
375         network->type       = type;
376         network->identifier = ident;
377
378         network_list = g_slist_append(network_list, network);
379
380         return network;
381 }
382
383 /**
384  * connman_network_ref:
385  * @network: network structure
386  *
387  * Increase reference counter of  network
388  */
389 struct connman_network *connman_network_ref(struct connman_network *network)
390 {
391         DBG("network %p name %s refcount %d", network, network->name,
392                 network->refcount + 1);
393
394         __sync_fetch_and_add(&network->refcount, 1);
395
396         return network;
397 }
398
399 /**
400  * connman_network_unref:
401  * @network: network structure
402  *
403  * Decrease reference counter of network
404  */
405 void connman_network_unref(struct connman_network *network)
406 {
407         DBG("network %p name %s refcount %d", network, network->name,
408                 network->refcount - 1);
409
410         if (__sync_fetch_and_sub(&network->refcount, 1) != 1)
411                 return;
412
413         network_list = g_slist_remove(network_list, network);
414
415         network_destruct(network);
416 }
417
418 const char *__connman_network_get_type(struct connman_network *network)
419 {
420         return type2string(network->type);
421 }
422
423 /**
424  * connman_network_get_type:
425  * @network: network structure
426  *
427  * Get type of network
428  */
429 enum connman_network_type connman_network_get_type(struct connman_network *network)
430 {
431         return network->type;
432 }
433
434 /**
435  * connman_network_get_identifier:
436  * @network: network structure
437  *
438  * Get identifier of network
439  */
440 const char *connman_network_get_identifier(struct connman_network *network)
441 {
442         return network->identifier;
443 }
444
445 /**
446  * connman_network_set_index:
447  * @network: network structure
448  * @index: index number
449  *
450  * Set index number of network
451  */
452 void connman_network_set_index(struct connman_network *network, int index)
453 {
454         struct connman_service *service;
455         struct connman_ipconfig *ipconfig;
456
457         service = __connman_service_lookup_from_network(network);
458         if (service == NULL)
459                 goto done;
460
461         ipconfig = __connman_service_get_ip4config(service);
462
463         DBG("index %d service %p ip4config %p", network->index,
464                 service, ipconfig);
465
466         if (network->index < 0 && ipconfig == NULL) {
467
468                 ipconfig = __connman_service_get_ip4config(service);
469                 if (ipconfig == NULL)
470                         /*
471                          * This is needed for plugins that havent set their
472                          * ipconfig layer yet, due to not being able to get
473                          * a network index prior to creating a service.
474                          */
475                         __connman_service_create_ip4config(service, index);
476                 else
477                         __connman_ipconfig_set_index(ipconfig, index);
478
479         } else {
480                 /* If index changed, the index of ipconfig must be reset. */
481                 if (ipconfig == NULL)
482                         goto done;
483
484                 __connman_ipconfig_set_index(ipconfig, index);
485         }
486
487 done:
488         network->index = index;
489 }
490
491 /**
492  * connman_network_get_index:
493  * @network: network structure
494  *
495  * Get index number of network
496  */
497 int connman_network_get_index(struct connman_network *network)
498 {
499         return network->index;
500 }
501
502 /**
503  * connman_network_set_group:
504  * @network: network structure
505  * @group: group name
506  *
507  * Set group name for automatic clustering
508  */
509 void connman_network_set_group(struct connman_network *network,
510                                                         const char *group)
511 {
512         switch (network->type) {
513         case CONNMAN_NETWORK_TYPE_UNKNOWN:
514         case CONNMAN_NETWORK_TYPE_VENDOR:
515                 return;
516         case CONNMAN_NETWORK_TYPE_ETHERNET:
517         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
518         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
519         case CONNMAN_NETWORK_TYPE_CELLULAR:
520         case CONNMAN_NETWORK_TYPE_WIFI:
521         case CONNMAN_NETWORK_TYPE_WIMAX:
522                 break;
523         }
524
525         if (g_strcmp0(network->group, group) == 0) {
526                 if (group != NULL)
527                         __connman_service_update_from_network(network);
528                 return;
529         }
530
531         if (network->group != NULL) {
532                 __connman_service_remove_from_network(network);
533
534                 g_free(network->group);
535         }
536
537         network->group = g_strdup(group);
538
539         if (network->group != NULL)
540                 network_probe(network);
541 }
542
543 /**
544  * connman_network_get_group:
545  * @network: network structure
546  *
547  * Get group name for automatic clustering
548  */
549 const char *connman_network_get_group(struct connman_network *network)
550 {
551         return network->group;
552 }
553
554 const char *__connman_network_get_ident(struct connman_network *network)
555 {
556         if (network->device == NULL)
557                 return NULL;
558
559         return connman_device_get_ident(network->device);
560 }
561
562 connman_bool_t __connman_network_get_weakness(struct connman_network *network)
563 {
564         switch (network->type) {
565         case CONNMAN_NETWORK_TYPE_UNKNOWN:
566         case CONNMAN_NETWORK_TYPE_VENDOR:
567         case CONNMAN_NETWORK_TYPE_ETHERNET:
568         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
569         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
570         case CONNMAN_NETWORK_TYPE_CELLULAR:
571         case CONNMAN_NETWORK_TYPE_WIMAX:
572                 break;
573         case CONNMAN_NETWORK_TYPE_WIFI:
574                 if (g_strcmp0(network->wifi.mode, "adhoc") == 0)
575                         return TRUE;
576                 if (network->strength > 0 && network->strength < 20)
577                         return TRUE;
578                 break;
579         }
580
581         return FALSE;
582 }
583
584 connman_bool_t connman_network_get_connecting(struct connman_network *network)
585 {
586         return network->connecting;
587 }
588
589 /**
590  * connman_network_set_available:
591  * @network: network structure
592  * @available: availability state
593  *
594  * Change availability state of network (in range)
595  */
596 int connman_network_set_available(struct connman_network *network,
597                                                 connman_bool_t available)
598 {
599         DBG("network %p available %d", network, available);
600
601         if (network->available == available)
602                 return -EALREADY;
603
604         network->available = available;
605
606         return 0;
607 }
608
609 /**
610  * connman_network_get_available:
611  * @network: network structure
612  *
613  * Get network available setting
614  */
615 connman_bool_t connman_network_get_available(struct connman_network *network)
616 {
617         return network->available;
618 }
619
620 /**
621  * connman_network_set_associating:
622  * @network: network structure
623  * @associating: associating state
624  *
625  * Change associating state of network
626  */
627 int connman_network_set_associating(struct connman_network *network,
628                                                 connman_bool_t associating)
629 {
630         DBG("network %p associating %d", network, associating);
631
632         if (network->associating == associating)
633                 return -EALREADY;
634
635         network->associating = associating;
636
637         if (associating == TRUE) {
638                 struct connman_service *service;
639
640                 service = __connman_service_lookup_from_network(network);
641                 __connman_service_ipconfig_indicate_state(service,
642                                         CONNMAN_SERVICE_STATE_ASSOCIATION,
643                                         CONNMAN_IPCONFIG_TYPE_IPV4);
644                 __connman_service_ipconfig_indicate_state(service,
645                                         CONNMAN_SERVICE_STATE_ASSOCIATION,
646                                         CONNMAN_IPCONFIG_TYPE_IPV6);
647         }
648
649         return 0;
650 }
651
652 static void set_associate_error(struct connman_network *network)
653 {
654         struct connman_service *service;
655
656         if (network->associating == FALSE)
657                 return ;
658
659         network->associating = FALSE;
660
661         service = __connman_service_lookup_from_network(network);
662
663         __connman_service_ipconfig_indicate_state(service,
664                                         CONNMAN_SERVICE_STATE_FAILURE,
665                                         CONNMAN_IPCONFIG_TYPE_IPV4);
666 }
667
668 static void set_configure_error(struct connman_network *network)
669 {
670         struct connman_service *service;
671
672         network->connecting = FALSE;
673
674         service = __connman_service_lookup_from_network(network);
675
676         __connman_service_ipconfig_indicate_state(service,
677                                         CONNMAN_SERVICE_STATE_FAILURE,
678                                         CONNMAN_IPCONFIG_TYPE_IPV4);
679 }
680
681 static void set_invalid_key_error(struct connman_network *network)
682 {
683         struct connman_service *service;
684
685         service = __connman_service_lookup_from_network(network);
686
687         __connman_service_indicate_error(service,
688                                         CONNMAN_SERVICE_ERROR_INVALID_KEY);
689 }
690
691 static void set_connect_error(struct connman_network *network)
692 {
693         struct connman_service *service;
694
695         service = __connman_service_lookup_from_network(network);
696
697         __connman_service_indicate_error(service,
698                                         CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
699 }
700
701 void connman_network_set_ipv4_method(struct connman_network *network,
702                                         enum connman_ipconfig_method method)
703 {
704         struct connman_service *service;
705         struct connman_ipconfig *ipconfig;
706
707         service = __connman_service_lookup_from_network(network);
708         if (service == NULL)
709                 return;
710
711         ipconfig = __connman_service_get_ip4config(service);
712         if (ipconfig == NULL)
713                 return;
714
715         connman_ipconfig_set_method(ipconfig, method);
716 }
717
718 void connman_network_set_ipv6_method(struct connman_network *network,
719                                         enum connman_ipconfig_method method)
720 {
721         struct connman_service *service;
722         struct connman_ipconfig *ipconfig;
723
724         service = __connman_service_lookup_from_network(network);
725         if (service == NULL)
726                 return;
727
728         ipconfig = __connman_service_get_ip6config(service);
729         if (ipconfig == NULL)
730                 return;
731
732         connman_ipconfig_set_method(ipconfig, method);
733 }
734
735 void connman_network_set_error(struct connman_network *network,
736                                         enum connman_network_error error)
737 {
738         DBG("nework %p, error %d", network, error);
739
740         network->connecting = FALSE;
741
742         switch (error) {
743         case CONNMAN_NETWORK_ERROR_UNKNOWN:
744                 return;
745         case CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL:
746                 set_associate_error(network);
747                 break;
748         case CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL:
749                 set_configure_error(network);
750                 break;
751         case CONNMAN_NETWORK_ERROR_INVALID_KEY:
752                 set_invalid_key_error(network);
753                 break;
754         case CONNMAN_NETWORK_ERROR_CONNECT_FAIL:
755                 set_connect_error(network);
756                 break;
757         }
758
759         network_change(network);
760 }
761
762 void connman_network_clear_error(struct connman_network *network)
763 {
764         struct connman_service *service;
765
766         DBG("network %p", network);
767
768         if (network == NULL)
769                 return;
770
771         if (network->connecting == TRUE || network->associating == TRUE)
772                 return;
773
774         service = __connman_service_lookup_from_network(network);
775         __connman_service_clear_error(service);
776 }
777
778 static void set_configuration(struct connman_network *network)
779 {
780         struct connman_service *service;
781
782         DBG("network %p", network);
783
784         if (network->device == NULL)
785                 return;
786
787         __connman_device_set_network(network->device, network);
788
789         connman_device_set_disconnected(network->device, FALSE);
790
791         service = __connman_service_lookup_from_network(network);
792         __connman_service_ipconfig_indicate_state(service,
793                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
794                                         CONNMAN_IPCONFIG_TYPE_IPV4);
795 }
796
797 static void dhcp_success(struct connman_network *network)
798 {
799         struct connman_service *service;
800         struct connman_ipconfig *ipconfig_ipv4;
801         int err;
802
803         service = __connman_service_lookup_from_network(network);
804         if (service == NULL)
805                 goto err;
806
807         connman_network_set_associating(network, FALSE);
808
809         network->connecting = FALSE;
810
811         ipconfig_ipv4 = __connman_service_get_ip4config(service);
812         err = __connman_ipconfig_address_add(ipconfig_ipv4);
813         if (err < 0)
814                 goto err;
815
816         err = __connman_ipconfig_gateway_add(ipconfig_ipv4);
817         if (err < 0)
818                 goto err;
819
820         return;
821
822 err:
823         connman_network_set_error(network,
824                                 CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
825 }
826
827 static void dhcp_failure(struct connman_network *network)
828 {
829         struct connman_service *service;
830
831         service = __connman_service_lookup_from_network(network);
832         if (service == NULL)
833                 return;
834
835         __connman_service_ipconfig_indicate_state(service,
836                                         CONNMAN_SERVICE_STATE_IDLE,
837                                         CONNMAN_IPCONFIG_TYPE_IPV4);
838 }
839
840 static void dhcp_callback(struct connman_network *network,
841                         connman_bool_t success)
842 {
843         DBG("success %d", success);
844
845         if (success == TRUE)
846                 dhcp_success(network);
847         else
848                 dhcp_failure(network);
849 }
850
851 static int set_connected_fixed(struct connman_network *network)
852 {
853         struct connman_service *service;
854         struct connman_ipconfig *ipconfig_ipv4;
855         int err;
856
857         DBG("");
858
859         service = __connman_service_lookup_from_network(network);
860
861         ipconfig_ipv4 = __connman_service_get_ip4config(service);
862
863         set_configuration(network);
864
865         network->connecting = FALSE;
866
867         connman_network_set_associating(network, FALSE);
868
869         err = __connman_ipconfig_address_add(ipconfig_ipv4);
870         if (err < 0)
871                 goto err;
872
873         err = __connman_ipconfig_gateway_add(ipconfig_ipv4);
874         if (err < 0)
875                 goto err;
876
877         return 0;
878
879 err:
880         connman_network_set_error(network,
881                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
882
883         return err;
884 }
885
886 static void set_connected_manual(struct connman_network *network)
887 {
888         struct connman_service *service;
889         struct connman_ipconfig *ipconfig;
890         int err;
891
892         DBG("network %p", network);
893
894         service = __connman_service_lookup_from_network(network);
895
896         ipconfig = __connman_service_get_ip4config(service);
897
898         if (__connman_ipconfig_get_local(ipconfig) == NULL)
899                 __connman_service_read_ip4config(service);
900
901         set_configuration(network);
902
903         err = __connman_ipconfig_address_add(ipconfig);
904         if (err < 0)
905                 goto err;
906
907         err = __connman_ipconfig_gateway_add(ipconfig);
908         if (err < 0)
909                 goto err;
910
911         network->connecting = FALSE;
912
913         connman_network_set_associating(network, FALSE);
914
915         return;
916
917 err:
918         connman_network_set_error(network,
919                                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
920         return;
921 }
922
923 static int set_connected_dhcp(struct connman_network *network)
924 {
925         int err;
926
927         DBG("network %p", network);
928
929         set_configuration(network);
930
931         err = __connman_dhcp_start(network, dhcp_callback);
932         if (err < 0) {
933                 connman_error("Can not request DHCP lease");
934                 return err;
935         }
936
937         return 0;
938 }
939
940 static int manual_ipv6_set(struct connman_network *network,
941                                 struct connman_ipconfig *ipconfig_ipv6)
942 {
943         struct connman_service *service;
944         int err;
945
946         DBG("network %p ipv6 %p", network, ipconfig_ipv6);
947
948         service = __connman_service_lookup_from_network(network);
949         if (service == NULL)
950                 return -EINVAL;
951
952         if (__connman_ipconfig_get_local(ipconfig_ipv6) == NULL)
953                 __connman_service_read_ip6config(service);
954
955         err = __connman_ipconfig_address_add(ipconfig_ipv6);
956         if (err < 0) {
957                 connman_network_set_error(network,
958                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
959                 return err;
960         }
961
962         err = __connman_ipconfig_gateway_add(ipconfig_ipv6);
963         if (err < 0)
964                 return err;
965
966         __connman_connection_gateway_activate(service,
967                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
968
969         __connman_device_set_network(network->device, network);
970
971         connman_device_set_disconnected(network->device, FALSE);
972
973         network->connecting = FALSE;
974
975         return 0;
976 }
977
978 static void autoconf_ipv6_set(struct connman_network *network)
979 {
980         DBG("network %p", network);
981
982         __connman_device_set_network(network->device, network);
983
984         connman_device_set_disconnected(network->device, FALSE);
985
986         /* XXX: Append IPv6 nameservers here */
987
988         network->connecting = FALSE;
989 }
990
991 static gboolean set_connected(gpointer user_data)
992 {
993         struct connman_network *network = user_data;
994         struct connman_service *service;
995         struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
996         enum connman_ipconfig_method ipv4_method, ipv6_method;
997
998         service = __connman_service_lookup_from_network(network);
999
1000         ipconfig_ipv4 = __connman_service_get_ip4config(service);
1001         ipconfig_ipv6 = __connman_service_get_ip6config(service);
1002
1003         DBG("service %p ipv4 %p ipv6 %p", service, ipconfig_ipv4,
1004                 ipconfig_ipv6);
1005
1006         ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4);
1007         ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6);
1008
1009         DBG("method ipv4 %d ipv6 %d", ipv4_method, ipv6_method);
1010         DBG("network connected %d", network->connected);
1011
1012         if (network->connected == TRUE) {
1013                 int ret;
1014
1015                 switch (ipv6_method) {
1016                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1017                 case CONNMAN_IPCONFIG_METHOD_OFF:
1018                         break;
1019                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1020                         autoconf_ipv6_set(network);
1021                         break;
1022                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1023                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1024                         ret = manual_ipv6_set(network, ipconfig_ipv6);
1025                         if (ret != 0) {
1026                                 connman_network_set_error(network,
1027                                         CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
1028                                 return FALSE;
1029                         }
1030                         break;
1031                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1032                         break;
1033                 }
1034
1035                 switch (ipv4_method) {
1036                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1037                 case CONNMAN_IPCONFIG_METHOD_OFF:
1038                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1039                         return FALSE;
1040                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1041                         if (set_connected_fixed(network) < 0) {
1042                                 connman_network_set_error(network,
1043                                         CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
1044                                 return FALSE;
1045                         }
1046                         return TRUE;
1047                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1048                         set_connected_manual(network);
1049                         return TRUE;
1050                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1051                         if (set_connected_dhcp(network) < 0) {
1052                                 connman_network_set_error(network,
1053                                         CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
1054                                 return FALSE;
1055                         }
1056                 }
1057
1058         } else {
1059                 enum connman_service_state state;
1060
1061                 __connman_device_set_network(network->device, NULL);
1062
1063                 switch (ipv4_method) {
1064                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1065                 case CONNMAN_IPCONFIG_METHOD_OFF:
1066                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1067                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1068                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1069                         break;
1070                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1071                         __connman_dhcp_stop(network);
1072                         break;
1073                 }
1074
1075                 /*
1076                  * We only set the disconnect state if we were not in idle
1077                  * or in failure. It does not make sense to go to disconnect
1078                  * state if we were not connected.
1079                  */
1080                 state = __connman_service_ipconfig_get_state(service,
1081                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1082                 if (state != CONNMAN_SERVICE_STATE_IDLE &&
1083                                         state != CONNMAN_SERVICE_STATE_FAILURE)
1084                         __connman_service_ipconfig_indicate_state(service,
1085                                         CONNMAN_SERVICE_STATE_DISCONNECT,
1086                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1087
1088                 state = __connman_service_ipconfig_get_state(service,
1089                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1090                 if (state != CONNMAN_SERVICE_STATE_IDLE &&
1091                                         state != CONNMAN_SERVICE_STATE_FAILURE)
1092                         __connman_service_ipconfig_indicate_state(service,
1093                                         CONNMAN_SERVICE_STATE_DISCONNECT,
1094                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1095
1096                 __connman_connection_gateway_remove(service,
1097                                                 CONNMAN_IPCONFIG_TYPE_ALL);
1098
1099                 __connman_ipconfig_address_unset(ipconfig_ipv4);
1100                 __connman_ipconfig_address_unset(ipconfig_ipv6);
1101
1102                 /*
1103                  * Special handling for IPv6 autoconfigured address.
1104                  * The simplest way to remove autoconfigured routes is to
1105                  * disable IPv6 temporarily so that kernel will do the cleanup
1106                  * automagically.
1107                  */
1108                 if (ipv6_method == CONNMAN_IPCONFIG_METHOD_AUTO) {
1109                         __connman_ipconfig_disable_ipv6(ipconfig_ipv6);
1110                         __connman_ipconfig_enable_ipv6(ipconfig_ipv6);
1111                 }
1112
1113                 __connman_service_ipconfig_indicate_state(service,
1114                                         CONNMAN_SERVICE_STATE_IDLE,
1115                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1116
1117                 __connman_service_ipconfig_indicate_state(service,
1118                                         CONNMAN_SERVICE_STATE_IDLE,
1119                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1120         }
1121
1122         network->connecting = FALSE;
1123
1124         connman_network_set_associating(network, FALSE);
1125
1126         return FALSE;
1127 }
1128
1129 /**
1130  * connman_network_set_connected:
1131  * @network: network structure
1132  * @connected: connected state
1133  *
1134  * Change connected state of network
1135  */
1136 int connman_network_set_connected(struct connman_network *network,
1137                                                 connman_bool_t connected)
1138 {
1139         DBG("network %p connected %d", network, connected);
1140
1141         if ((network->connecting == TRUE || network->associating == TRUE) &&
1142                                                         connected == FALSE) {
1143                 connman_network_set_error(network,
1144                                         CONNMAN_NETWORK_ERROR_CONNECT_FAIL);
1145                 __connman_network_disconnect(network);
1146         }
1147
1148         if (network->connected == connected)
1149                 return -EALREADY;
1150
1151         network->connected = connected;
1152
1153         set_connected(network);
1154
1155         return 0;
1156 }
1157
1158 /**
1159  * connman_network_get_connected:
1160  * @network: network structure
1161  *
1162  * Get network connection status
1163  */
1164 connman_bool_t connman_network_get_connected(struct connman_network *network)
1165 {
1166         return network->connected;
1167 }
1168
1169 /**
1170  * connman_network_get_associating:
1171  * @network: network structure
1172  *
1173  * Get network associating status
1174  */
1175 connman_bool_t connman_network_get_associating(struct connman_network *network)
1176 {
1177         return network->associating;
1178 }
1179
1180 /**
1181  * __connman_network_connect:
1182  * @network: network structure
1183  *
1184  * Connect network
1185  */
1186 int __connman_network_connect(struct connman_network *network)
1187 {
1188         int err;
1189
1190         DBG("network %p", network);
1191
1192         if (network->connected == TRUE)
1193                 return -EISCONN;
1194
1195         if (network->connecting == TRUE || network->associating == TRUE)
1196                 return -EALREADY;
1197
1198         if (network->driver == NULL)
1199                 return -EUNATCH;
1200
1201         if (network->driver->connect == NULL)
1202                 return -ENOSYS;
1203
1204         if (network->device == NULL)
1205                 return -ENODEV;
1206
1207         network->connecting = TRUE;
1208
1209         __connman_device_disconnect(network->device);
1210
1211         err = network->driver->connect(network);
1212         if (err < 0) {
1213                 if (err == -EINPROGRESS)
1214                         connman_network_set_associating(network, TRUE);
1215                 else {
1216                         network->connecting = FALSE;
1217                 }
1218
1219                 return err;
1220         }
1221
1222         network->connected = TRUE;
1223         set_connected(network);
1224
1225         return err;
1226 }
1227
1228 /**
1229  * __connman_network_disconnect:
1230  * @network: network structure
1231  *
1232  * Disconnect network
1233  */
1234 int __connman_network_disconnect(struct connman_network *network)
1235 {
1236         int err;
1237
1238         DBG("network %p", network);
1239
1240         if (network->connected == FALSE && network->connecting == FALSE &&
1241                                                 network->associating == FALSE)
1242                 return -ENOTCONN;
1243
1244         if (network->driver == NULL)
1245                 return -EUNATCH;
1246
1247         if (network->driver->disconnect == NULL)
1248                 return -ENOSYS;
1249
1250         network->connecting = FALSE;
1251
1252         err = network->driver->disconnect(network);
1253         if (err == 0) {
1254                 connman_network_set_connected(network, FALSE);
1255                 set_connected(network);
1256         }
1257
1258         return err;
1259 }
1260
1261 static int manual_ipv4_set(struct connman_network *network,
1262                                 struct connman_ipconfig *ipconfig)
1263 {
1264         struct connman_service *service;
1265         int err;
1266
1267         service = __connman_service_lookup_from_network(network);
1268         if (service == NULL)
1269                 return -EINVAL;
1270
1271         err = __connman_ipconfig_address_add(ipconfig);
1272         if (err < 0) {
1273                 connman_network_set_error(network,
1274                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
1275                 return err;
1276         }
1277
1278         return __connman_ipconfig_gateway_add(ipconfig);
1279 }
1280
1281 int __connman_network_clear_ipconfig(struct connman_network *network,
1282                                         struct connman_ipconfig *ipconfig)
1283 {
1284         struct connman_service *service;
1285         enum connman_ipconfig_method method;
1286         enum connman_ipconfig_type type;
1287
1288         service = __connman_service_lookup_from_network(network);
1289         if (service == NULL)
1290                 return -EINVAL;
1291
1292         method = __connman_ipconfig_get_method(ipconfig);
1293         type = __connman_ipconfig_get_config_type(ipconfig);
1294
1295         switch (method) {
1296         case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1297         case CONNMAN_IPCONFIG_METHOD_OFF:
1298         case CONNMAN_IPCONFIG_METHOD_FIXED:
1299         case CONNMAN_IPCONFIG_METHOD_AUTO:
1300                 return -EINVAL;
1301         case CONNMAN_IPCONFIG_METHOD_MANUAL:
1302                 __connman_ipconfig_address_remove(ipconfig);
1303                 break;
1304         case CONNMAN_IPCONFIG_METHOD_DHCP:
1305                 __connman_dhcp_stop(network);
1306                 break;
1307         }
1308
1309         if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1310                 __connman_service_ipconfig_indicate_state(service,
1311                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
1312                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1313         else if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1314                 __connman_service_ipconfig_indicate_state(service,
1315                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
1316                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1317
1318         return 0;
1319 }
1320
1321 int __connman_network_set_ipconfig(struct connman_network *network,
1322                                         struct connman_ipconfig *ipconfig_ipv4,
1323                                         struct connman_ipconfig *ipconfig_ipv6)
1324 {
1325         enum connman_ipconfig_method method;
1326         int ret;
1327
1328         if (network == NULL)
1329                 return -EINVAL;
1330
1331         if (ipconfig_ipv6) {
1332                 method = __connman_ipconfig_get_method(ipconfig_ipv6);
1333
1334                 switch (method) {
1335                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1336                 case CONNMAN_IPCONFIG_METHOD_OFF:
1337                         break;
1338                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1339                         autoconf_ipv6_set(network);
1340                         break;
1341                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1342                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1343                         ret = manual_ipv6_set(network, ipconfig_ipv6);
1344                         if (ret != 0) {
1345                                 connman_network_set_error(network,
1346                                         CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
1347                                 return ret;
1348                         }
1349                         break;
1350                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1351                         break;
1352                 }
1353         }
1354
1355         if (ipconfig_ipv4) {
1356                 method = __connman_ipconfig_get_method(ipconfig_ipv4);
1357
1358                 switch (method) {
1359                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1360                 case CONNMAN_IPCONFIG_METHOD_OFF:
1361                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1362                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1363                         return -EINVAL;
1364                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1365                         return manual_ipv4_set(network, ipconfig_ipv4);
1366                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1367                         return __connman_dhcp_start(network, dhcp_callback);
1368                 }
1369         }
1370
1371         return 0;
1372 }
1373
1374 int connman_network_set_ipaddress(struct connman_network *network,
1375                                         struct connman_ipaddress *ipaddress)
1376 {
1377         struct connman_service *service;
1378         struct connman_ipconfig *ipconfig = NULL;
1379
1380         DBG("network %p", network);
1381
1382         service = __connman_service_lookup_from_network(network);
1383         if (service == NULL)
1384                 return -EINVAL;
1385
1386         ipconfig = __connman_service_get_ipconfig(service, ipaddress->family);
1387         if (ipconfig == NULL)
1388                 return -EINVAL;
1389
1390         __connman_ipconfig_set_local(ipconfig, ipaddress->local);
1391         __connman_ipconfig_set_peer(ipconfig, ipaddress->peer);
1392         __connman_ipconfig_set_broadcast(ipconfig, ipaddress->broadcast);
1393         __connman_ipconfig_set_prefixlen(ipconfig, ipaddress->prefixlen);
1394         __connman_ipconfig_set_gateway(ipconfig, ipaddress->gateway);
1395
1396         return 0;
1397 }
1398
1399 int connman_network_set_nameservers(struct connman_network *network,
1400                                 const char *nameservers)
1401 {
1402         struct connman_service *service;
1403         char **nameservers_array = NULL;
1404         int i;
1405
1406         DBG("network %p nameservers %s", network, nameservers);
1407
1408         service = __connman_service_lookup_from_network(network);
1409         if (service == NULL)
1410                 return -EINVAL;
1411
1412         __connman_service_nameserver_clear(service);
1413
1414         if (nameservers != NULL)
1415                 nameservers_array = g_strsplit(nameservers, " ", 0);
1416
1417         for (i = 0; nameservers_array[i] != NULL; i++) {
1418                 __connman_service_nameserver_append(service,
1419                                                 nameservers_array[i]);
1420         }
1421
1422         g_strfreev(nameservers_array);
1423
1424         return 0;
1425 }
1426
1427 int connman_network_set_domain(struct connman_network *network,
1428                                 const char *domain)
1429 {
1430         struct connman_service *service;
1431
1432         DBG("network %p domain %s", network, domain);
1433
1434         service = __connman_service_lookup_from_network(network);
1435         if (service == NULL)
1436                 return -EINVAL;
1437
1438         __connman_service_set_domainname(service, domain);
1439
1440         return 0;
1441 }
1442
1443 /**
1444  * connman_network_set_name:
1445  * @network: network structure
1446  * @name: name value
1447  *
1448  * Set display name value for network
1449  */
1450 int connman_network_set_name(struct connman_network *network,
1451                                                         const char *name)
1452 {
1453         DBG("network %p name %s", network, name);
1454
1455         g_free(network->name);
1456         network->name = g_strdup(name);
1457
1458         return 0;
1459 }
1460
1461 /**
1462  * connman_network_set_strength:
1463  * @network: network structure
1464  * @strength: strength value
1465  *
1466  * Set signal strength value for network
1467  */
1468
1469 int connman_network_set_strength(struct connman_network *network,
1470                                                 connman_uint8_t strength)
1471 {
1472         DBG("network %p strengh %d", network, strength);
1473
1474         network->strength = strength;
1475
1476         return 0;
1477 }
1478
1479 connman_uint8_t connman_network_get_strength(struct connman_network *network)
1480 {
1481         return network->strength;
1482 }
1483
1484 int connman_network_set_frequency(struct connman_network *network,
1485                                                 connman_uint16_t frequency)
1486 {
1487         DBG("network %p frequency %d", network, frequency);
1488
1489         network->frequency = frequency;
1490
1491         return 0;
1492 }
1493
1494 connman_uint16_t connman_network_get_frequency(struct connman_network *network)
1495 {
1496         return network->frequency;
1497 }
1498
1499 int connman_network_set_wifi_channel(struct connman_network *network,
1500                                                 connman_uint16_t channel)
1501 {
1502         DBG("network %p wifi channel %d", network, channel);
1503
1504         network->wifi.channel = channel;
1505
1506         return 0;
1507 }
1508
1509 connman_uint16_t connman_network_get_wifi_channel(struct connman_network *network)
1510 {
1511         return network->wifi.channel;
1512 }
1513
1514 /**
1515  * connman_network_set_roaming:
1516  * @network: network structure
1517  * @roaming: roaming state
1518  *
1519  * Set roaming state for network
1520  */
1521 int connman_network_set_roaming(struct connman_network *network,
1522                                                 connman_bool_t roaming)
1523 {
1524         DBG("network %p roaming %d", network, roaming);
1525
1526         network->roaming = roaming;
1527
1528         return 0;
1529 }
1530
1531 /**
1532  * connman_network_set_string:
1533  * @network: network structure
1534  * @key: unique identifier
1535  * @value: string value
1536  *
1537  * Set string value for specific key
1538  */
1539 int connman_network_set_string(struct connman_network *network,
1540                                         const char *key, const char *value)
1541 {
1542         DBG("network %p key %s value %s", network, key, value);
1543
1544         if (g_strcmp0(key, "Name") == 0)
1545                 return connman_network_set_name(network, value);
1546
1547         if (g_str_equal(key, "Path") == TRUE) {
1548                 g_free(network->path);
1549                 network->path = g_strdup(value);
1550         } else if (g_str_equal(key, "Node") == TRUE) {
1551                 g_free(network->node);
1552                 network->node = g_strdup(value);
1553         } else if (g_str_equal(key, "WiFi.Mode") == TRUE) {
1554                 g_free(network->wifi.mode);
1555                 network->wifi.mode = g_strdup(value);
1556         } else if (g_str_equal(key, "WiFi.Security") == TRUE) {
1557                 g_free(network->wifi.security);
1558                 network->wifi.security = g_strdup(value);
1559         } else if (g_str_equal(key, "WiFi.Passphrase") == TRUE) {
1560                 g_free(network->wifi.passphrase);
1561                 network->wifi.passphrase = g_strdup(value);
1562         } else if (g_str_equal(key, "WiFi.AgentPassphrase") == TRUE) {
1563                 g_free(network->wifi.agent_passphrase);
1564                 network->wifi.agent_passphrase = g_strdup(value);
1565         } else if (g_str_equal(key, "WiFi.EAP") == TRUE) {
1566                 g_free(network->wifi.eap);
1567                 network->wifi.eap = g_strdup(value);
1568         } else if (g_str_equal(key, "WiFi.Identity") == TRUE) {
1569                 g_free(network->wifi.identity);
1570                 network->wifi.identity = g_strdup(value);
1571         } else if (g_str_equal(key, "WiFi.AgentIdentity") == TRUE) {
1572                 g_free(network->wifi.agent_identity);
1573                 network->wifi.agent_identity = g_strdup(value);
1574         } else if (g_str_equal(key, "WiFi.CACertFile") == TRUE) {
1575                 g_free(network->wifi.ca_cert_path);
1576                 network->wifi.ca_cert_path = g_strdup(value);
1577         } else if (g_str_equal(key, "WiFi.ClientCertFile") == TRUE) {
1578                 g_free(network->wifi.client_cert_path);
1579                 network->wifi.client_cert_path = g_strdup(value);
1580         } else if (g_str_equal(key, "WiFi.PrivateKeyFile") == TRUE) {
1581                 g_free(network->wifi.private_key_path);
1582                 network->wifi.private_key_path = g_strdup(value);
1583         } else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase") == TRUE) {
1584                 g_free(network->wifi.private_key_passphrase);
1585                 network->wifi.private_key_passphrase = g_strdup(value);
1586         } else if (g_str_equal(key, "WiFi.Phase2") == TRUE) {
1587                 g_free(network->wifi.phase2_auth);
1588                 network->wifi.phase2_auth = g_strdup(value);
1589         } else if (g_str_equal(key, "WiFi.PinWPS") == TRUE) {
1590                 g_free(network->wifi.pin_wps);
1591                 network->wifi.pin_wps = g_strdup(value);
1592         } else {
1593                 return -EINVAL;
1594         }
1595
1596         return 0;
1597 }
1598
1599 /**
1600  * connman_network_get_string:
1601  * @network: network structure
1602  * @key: unique identifier
1603  *
1604  * Get string value for specific key
1605  */
1606 const char *connman_network_get_string(struct connman_network *network,
1607                                                         const char *key)
1608 {
1609         DBG("network %p key %s", network, key);
1610
1611         if (g_str_equal(key, "Path") == TRUE)
1612                 return network->path;
1613         else if (g_str_equal(key, "Name") == TRUE)
1614                 return network->name;
1615         else if (g_str_equal(key, "Node") == TRUE)
1616                 return network->node;
1617         else if (g_str_equal(key, "WiFi.Mode") == TRUE)
1618                 return network->wifi.mode;
1619         else if (g_str_equal(key, "WiFi.Security") == TRUE)
1620                 return network->wifi.security;
1621         else if (g_str_equal(key, "WiFi.Passphrase") == TRUE)
1622                 return network->wifi.passphrase;
1623         else if (g_str_equal(key, "WiFi.AgentPassphrase") == TRUE)
1624                 return network->wifi.agent_passphrase;
1625         else if (g_str_equal(key, "WiFi.EAP") == TRUE)
1626                 return network->wifi.eap;
1627         else if (g_str_equal(key, "WiFi.Identity") == TRUE)
1628                 return network->wifi.identity;
1629         else if (g_str_equal(key, "WiFi.AgentIdentity") == TRUE)
1630                 return network->wifi.agent_identity;
1631         else if (g_str_equal(key, "WiFi.CACertFile") == TRUE)
1632                 return network->wifi.ca_cert_path;
1633         else if (g_str_equal(key, "WiFi.ClientCertFile") == TRUE)
1634                 return network->wifi.client_cert_path;
1635         else if (g_str_equal(key, "WiFi.PrivateKeyFile") == TRUE)
1636                 return network->wifi.private_key_path;
1637         else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase") == TRUE)
1638                 return network->wifi.private_key_passphrase;
1639         else if (g_str_equal(key, "WiFi.Phase2") == TRUE)
1640                 return network->wifi.phase2_auth;
1641         else if (g_str_equal(key, "WiFi.PinWPS") == TRUE)
1642                 return network->wifi.pin_wps;
1643
1644         return NULL;
1645 }
1646
1647 /**
1648  * connman_network_set_bool:
1649  * @network: network structure
1650  * @key: unique identifier
1651  * @value: boolean value
1652  *
1653  * Set boolean value for specific key
1654  */
1655 int connman_network_set_bool(struct connman_network *network,
1656                                         const char *key, connman_bool_t value)
1657 {
1658         DBG("network %p key %s value %d", network, key, value);
1659
1660         if (g_strcmp0(key, "Roaming") == 0)
1661                 return connman_network_set_roaming(network, value);
1662         else if (g_strcmp0(key, "WiFi.WPS") == 0)
1663                 network->wifi.wps = value;
1664         else if (g_strcmp0(key, "WiFi.UseWPS") == 0)
1665                 network->wifi.use_wps = value;
1666
1667         return -EINVAL;
1668 }
1669
1670 /**
1671  * connman_network_get_bool:
1672  * @network: network structure
1673  * @key: unique identifier
1674  *
1675  * Get boolean value for specific key
1676  */
1677 connman_bool_t connman_network_get_bool(struct connman_network *network,
1678                                                         const char *key)
1679 {
1680         DBG("network %p key %s", network, key);
1681
1682         if (g_str_equal(key, "Roaming") == TRUE)
1683                 return network->roaming;
1684         else if (g_str_equal(key, "WiFi.WPS") == TRUE)
1685                 return network->wifi.wps;
1686         else if (g_str_equal(key, "WiFi.UseWPS") == TRUE)
1687                 return network->wifi.use_wps;
1688
1689         return FALSE;
1690 }
1691
1692 /**
1693  * connman_network_set_blob:
1694  * @network: network structure
1695  * @key: unique identifier
1696  * @data: blob data
1697  * @size: blob size
1698  *
1699  * Set binary blob value for specific key
1700  */
1701 int connman_network_set_blob(struct connman_network *network,
1702                         const char *key, const void *data, unsigned int size)
1703 {
1704         DBG("network %p key %s size %d", network, key, size);
1705
1706         if (g_str_equal(key, "WiFi.SSID") == TRUE) {
1707                 g_free(network->wifi.ssid);
1708                 network->wifi.ssid = g_try_malloc(size);
1709                 if (network->wifi.ssid != NULL) {
1710                         memcpy(network->wifi.ssid, data, size);
1711                         network->wifi.ssid_len = size;
1712                 } else
1713                         network->wifi.ssid_len = 0;
1714         } else {
1715                 return -EINVAL;
1716         }
1717
1718         return 0;
1719 }
1720
1721 /**
1722  * connman_network_get_blob:
1723  * @network: network structure
1724  * @key: unique identifier
1725  * @size: pointer to blob size
1726  *
1727  * Get binary blob value for specific key
1728  */
1729 const void *connman_network_get_blob(struct connman_network *network,
1730                                         const char *key, unsigned int *size)
1731 {
1732         DBG("network %p key %s", network, key);
1733
1734         if (g_str_equal(key, "WiFi.SSID") == TRUE) {
1735                 if (size != NULL)
1736                         *size = network->wifi.ssid_len;
1737                 return network->wifi.ssid;
1738         }
1739
1740         return NULL;
1741 }
1742
1743 void __connman_network_set_device(struct connman_network *network,
1744                                         struct connman_device *device)
1745 {
1746         if (network->device == device)
1747                 return;
1748
1749         if (network->device != NULL)
1750                 network_remove(network);
1751
1752         network->device = device;
1753
1754         if (network->device != NULL)
1755                 network_probe(network);
1756 }
1757
1758 /**
1759  * connman_network_get_device:
1760  * @network: network structure
1761  *
1762  * Get parent device of network
1763  */
1764 struct connman_device *connman_network_get_device(struct connman_network *network)
1765 {
1766         return network->device;
1767 }
1768
1769 /**
1770  * connman_network_get_data:
1771  * @network: network structure
1772  *
1773  * Get private network data pointer
1774  */
1775 void *connman_network_get_data(struct connman_network *network)
1776 {
1777         return network->driver_data;
1778 }
1779
1780 /**
1781  * connman_network_set_data:
1782  * @network: network structure
1783  * @data: data pointer
1784  *
1785  * Set private network data pointer
1786  */
1787 void connman_network_set_data(struct connman_network *network, void *data)
1788 {
1789         network->driver_data = data;
1790 }
1791
1792 void connman_network_update(struct connman_network *network)
1793 {
1794         switch (network->type) {
1795         case CONNMAN_NETWORK_TYPE_UNKNOWN:
1796         case CONNMAN_NETWORK_TYPE_VENDOR:
1797                 return;
1798         case CONNMAN_NETWORK_TYPE_ETHERNET:
1799         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
1800         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
1801         case CONNMAN_NETWORK_TYPE_CELLULAR:
1802         case CONNMAN_NETWORK_TYPE_WIFI:
1803         case CONNMAN_NETWORK_TYPE_WIMAX:
1804                 break;
1805         }
1806
1807         if (network->group != NULL)
1808                 __connman_service_update_from_network(network);
1809 }
1810
1811 int __connman_network_init(void)
1812 {
1813         DBG("");
1814
1815         return 0;
1816 }
1817
1818 void __connman_network_cleanup(void)
1819 {
1820         DBG("");
1821 }