network: Add functionality to connect a hidden network
[profile/ivi/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         service = __connman_service_lookup_from_network(network);
657
658         __connman_service_indicate_error(service,
659                                         CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
660 }
661
662 static void set_configure_error(struct connman_network *network)
663 {
664         struct connman_service *service;
665
666         service = __connman_service_lookup_from_network(network);
667
668         __connman_service_indicate_error(service,
669                                         CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
670 }
671
672 static void set_invalid_key_error(struct connman_network *network)
673 {
674         struct connman_service *service;
675
676         service = __connman_service_lookup_from_network(network);
677
678         __connman_service_indicate_error(service,
679                                         CONNMAN_SERVICE_ERROR_INVALID_KEY);
680 }
681
682 static void set_connect_error(struct connman_network *network)
683 {
684         struct connman_service *service;
685
686         service = __connman_service_lookup_from_network(network);
687
688         __connman_service_indicate_error(service,
689                                         CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
690 }
691
692 void connman_network_set_ipv4_method(struct connman_network *network,
693                                         enum connman_ipconfig_method method)
694 {
695         struct connman_service *service;
696         struct connman_ipconfig *ipconfig;
697
698         service = __connman_service_lookup_from_network(network);
699         if (service == NULL)
700                 return;
701
702         ipconfig = __connman_service_get_ip4config(service);
703         if (ipconfig == NULL)
704                 return;
705
706         connman_ipconfig_set_method(ipconfig, method);
707 }
708
709 void connman_network_set_ipv6_method(struct connman_network *network,
710                                         enum connman_ipconfig_method method)
711 {
712         struct connman_service *service;
713         struct connman_ipconfig *ipconfig;
714
715         service = __connman_service_lookup_from_network(network);
716         if (service == NULL)
717                 return;
718
719         ipconfig = __connman_service_get_ip6config(service);
720         if (ipconfig == NULL)
721                 return;
722
723         connman_ipconfig_set_method(ipconfig, method);
724 }
725
726 void connman_network_set_error(struct connman_network *network,
727                                         enum connman_network_error error)
728 {
729         DBG("nework %p, error %d", network, error);
730
731         network->connecting = FALSE;
732         network->associating = FALSE;
733
734         switch (error) {
735         case CONNMAN_NETWORK_ERROR_UNKNOWN:
736                 return;
737         case CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL:
738                 set_associate_error(network);
739                 break;
740         case CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL:
741                 set_configure_error(network);
742                 break;
743         case CONNMAN_NETWORK_ERROR_INVALID_KEY:
744                 set_invalid_key_error(network);
745                 break;
746         case CONNMAN_NETWORK_ERROR_CONNECT_FAIL:
747                 set_connect_error(network);
748                 break;
749         }
750
751         network_change(network);
752 }
753
754 void connman_network_clear_error(struct connman_network *network)
755 {
756         struct connman_service *service;
757
758         DBG("network %p", network);
759
760         if (network == NULL)
761                 return;
762
763         if (network->connecting == TRUE || network->associating == TRUE)
764                 return;
765
766         service = __connman_service_lookup_from_network(network);
767         __connman_service_clear_error(service);
768 }
769
770 static void set_configuration(struct connman_network *network)
771 {
772         struct connman_service *service;
773
774         DBG("network %p", network);
775
776         if (network->device == NULL)
777                 return;
778
779         __connman_device_set_network(network->device, network);
780
781         connman_device_set_disconnected(network->device, FALSE);
782
783         service = __connman_service_lookup_from_network(network);
784         __connman_service_ipconfig_indicate_state(service,
785                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
786                                         CONNMAN_IPCONFIG_TYPE_IPV4);
787 }
788
789 static void dhcp_success(struct connman_network *network)
790 {
791         struct connman_service *service;
792         struct connman_ipconfig *ipconfig_ipv4;
793         int err;
794
795         service = __connman_service_lookup_from_network(network);
796         if (service == NULL)
797                 goto err;
798
799         connman_network_set_associating(network, FALSE);
800
801         network->connecting = FALSE;
802
803         ipconfig_ipv4 = __connman_service_get_ip4config(service);
804         err = __connman_ipconfig_address_add(ipconfig_ipv4);
805         if (err < 0)
806                 goto err;
807
808         err = __connman_ipconfig_gateway_add(ipconfig_ipv4);
809         if (err < 0)
810                 goto err;
811
812         return;
813
814 err:
815         connman_network_set_error(network,
816                                 CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
817 }
818
819 static void dhcp_failure(struct connman_network *network)
820 {
821         struct connman_service *service;
822
823         service = __connman_service_lookup_from_network(network);
824         if (service == NULL)
825                 return;
826
827         __connman_service_ipconfig_indicate_state(service,
828                                         CONNMAN_SERVICE_STATE_IDLE,
829                                         CONNMAN_IPCONFIG_TYPE_IPV4);
830 }
831
832 static void dhcp_callback(struct connman_network *network,
833                         connman_bool_t success)
834 {
835         DBG("success %d", success);
836
837         if (success == TRUE)
838                 dhcp_success(network);
839         else
840                 dhcp_failure(network);
841 }
842
843 static int set_connected_fixed(struct connman_network *network)
844 {
845         struct connman_service *service;
846         struct connman_ipconfig *ipconfig_ipv4;
847         int err;
848
849         DBG("");
850
851         service = __connman_service_lookup_from_network(network);
852
853         ipconfig_ipv4 = __connman_service_get_ip4config(service);
854
855         set_configuration(network);
856
857         network->connecting = FALSE;
858
859         connman_network_set_associating(network, FALSE);
860
861         err = __connman_ipconfig_address_add(ipconfig_ipv4);
862         if (err < 0)
863                 goto err;
864
865         err = __connman_ipconfig_gateway_add(ipconfig_ipv4);
866         if (err < 0)
867                 goto err;
868
869         return 0;
870
871 err:
872         connman_network_set_error(network,
873                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
874
875         return err;
876 }
877
878 static void set_connected_manual(struct connman_network *network)
879 {
880         struct connman_service *service;
881         struct connman_ipconfig *ipconfig;
882         int err;
883
884         DBG("network %p", network);
885
886         service = __connman_service_lookup_from_network(network);
887
888         ipconfig = __connman_service_get_ip4config(service);
889
890         if (__connman_ipconfig_get_local(ipconfig) == NULL)
891                 __connman_service_read_ip4config(service);
892
893         set_configuration(network);
894
895         err = __connman_ipconfig_address_add(ipconfig);
896         if (err < 0)
897                 goto err;
898
899         err = __connman_ipconfig_gateway_add(ipconfig);
900         if (err < 0)
901                 goto err;
902
903         network->connecting = FALSE;
904
905         connman_network_set_associating(network, FALSE);
906
907         return;
908
909 err:
910         connman_network_set_error(network,
911                                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
912         return;
913 }
914
915 static int set_connected_dhcp(struct connman_network *network)
916 {
917         int err;
918
919         DBG("network %p", network);
920
921         set_configuration(network);
922
923         err = __connman_dhcp_start(network, dhcp_callback);
924         if (err < 0) {
925                 connman_error("Can not request DHCP lease");
926                 return err;
927         }
928
929         return 0;
930 }
931
932 static int manual_ipv6_set(struct connman_network *network,
933                                 struct connman_ipconfig *ipconfig_ipv6)
934 {
935         struct connman_service *service;
936         int err;
937
938         DBG("network %p ipv6 %p", network, ipconfig_ipv6);
939
940         service = __connman_service_lookup_from_network(network);
941         if (service == NULL)
942                 return -EINVAL;
943
944         if (__connman_ipconfig_get_local(ipconfig_ipv6) == NULL)
945                 __connman_service_read_ip6config(service);
946
947         err = __connman_ipconfig_address_add(ipconfig_ipv6);
948         if (err < 0) {
949                 connman_network_set_error(network,
950                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
951                 return err;
952         }
953
954         err = __connman_ipconfig_gateway_add(ipconfig_ipv6);
955         if (err < 0)
956                 return err;
957
958         __connman_connection_gateway_activate(service,
959                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
960
961         __connman_device_set_network(network->device, network);
962
963         connman_device_set_disconnected(network->device, FALSE);
964
965         network->connecting = FALSE;
966
967         return 0;
968 }
969
970 static void autoconf_ipv6_set(struct connman_network *network)
971 {
972         DBG("network %p", network);
973
974         __connman_device_set_network(network->device, network);
975
976         connman_device_set_disconnected(network->device, FALSE);
977
978         /* XXX: Append IPv6 nameservers here */
979
980         network->connecting = FALSE;
981 }
982
983 static gboolean set_connected(gpointer user_data)
984 {
985         struct connman_network *network = user_data;
986         struct connman_service *service;
987         struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
988         enum connman_ipconfig_method ipv4_method, ipv6_method;
989
990         service = __connman_service_lookup_from_network(network);
991
992         ipconfig_ipv4 = __connman_service_get_ip4config(service);
993         ipconfig_ipv6 = __connman_service_get_ip6config(service);
994
995         DBG("service %p ipv4 %p ipv6 %p", service, ipconfig_ipv4,
996                 ipconfig_ipv6);
997
998         ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4);
999         ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6);
1000
1001         DBG("method ipv4 %d ipv6 %d", ipv4_method, ipv6_method);
1002         DBG("network connected %d", network->connected);
1003
1004         if (network->connected == TRUE) {
1005                 int ret;
1006
1007                 switch (ipv6_method) {
1008                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1009                 case CONNMAN_IPCONFIG_METHOD_OFF:
1010                         break;
1011                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1012                         autoconf_ipv6_set(network);
1013                         break;
1014                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1015                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1016                         ret = manual_ipv6_set(network, ipconfig_ipv6);
1017                         if (ret != 0) {
1018                                 connman_network_set_error(network,
1019                                         CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
1020                                 return FALSE;
1021                         }
1022                         break;
1023                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1024                         break;
1025                 }
1026
1027                 switch (ipv4_method) {
1028                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1029                 case CONNMAN_IPCONFIG_METHOD_OFF:
1030                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1031                         return FALSE;
1032                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1033                         if (set_connected_fixed(network) < 0) {
1034                                 connman_network_set_error(network,
1035                                         CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
1036                                 return FALSE;
1037                         }
1038                         return TRUE;
1039                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1040                         set_connected_manual(network);
1041                         return TRUE;
1042                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1043                         if (set_connected_dhcp(network) < 0) {
1044                                 connman_network_set_error(network,
1045                                         CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
1046                                 return FALSE;
1047                         }
1048                 }
1049
1050         } else {
1051                 enum connman_service_state state;
1052
1053                 __connman_device_set_network(network->device, NULL);
1054
1055                 switch (ipv4_method) {
1056                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1057                 case CONNMAN_IPCONFIG_METHOD_OFF:
1058                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1059                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1060                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1061                         break;
1062                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1063                         __connman_dhcp_stop(network);
1064                         break;
1065                 }
1066
1067                 /*
1068                  * We only set the disconnect state if we were not in idle
1069                  * or in failure. It does not make sense to go to disconnect
1070                  * state if we were not connected.
1071                  */
1072                 state = __connman_service_ipconfig_get_state(service,
1073                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1074                 if (state != CONNMAN_SERVICE_STATE_IDLE &&
1075                                         state != CONNMAN_SERVICE_STATE_FAILURE)
1076                         __connman_service_ipconfig_indicate_state(service,
1077                                         CONNMAN_SERVICE_STATE_DISCONNECT,
1078                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1079
1080                 state = __connman_service_ipconfig_get_state(service,
1081                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
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_IPV6);
1087
1088                 __connman_connection_gateway_remove(service,
1089                                                 CONNMAN_IPCONFIG_TYPE_ALL);
1090
1091                 __connman_ipconfig_address_unset(ipconfig_ipv4);
1092                 __connman_ipconfig_address_unset(ipconfig_ipv6);
1093
1094                 /*
1095                  * Special handling for IPv6 autoconfigured address.
1096                  * The simplest way to remove autoconfigured routes is to
1097                  * disable IPv6 temporarily so that kernel will do the cleanup
1098                  * automagically.
1099                  */
1100                 if (ipv6_method == CONNMAN_IPCONFIG_METHOD_AUTO) {
1101                         __connman_ipconfig_disable_ipv6(ipconfig_ipv6);
1102                         __connman_ipconfig_enable_ipv6(ipconfig_ipv6);
1103                 }
1104
1105                 __connman_service_ipconfig_indicate_state(service,
1106                                         CONNMAN_SERVICE_STATE_IDLE,
1107                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1108
1109                 __connman_service_ipconfig_indicate_state(service,
1110                                         CONNMAN_SERVICE_STATE_IDLE,
1111                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1112         }
1113
1114         network->connecting = FALSE;
1115
1116         connman_network_set_associating(network, FALSE);
1117
1118         return FALSE;
1119 }
1120
1121 /**
1122  * connman_network_set_connected:
1123  * @network: network structure
1124  * @connected: connected state
1125  *
1126  * Change connected state of network
1127  */
1128 int connman_network_set_connected(struct connman_network *network,
1129                                                 connman_bool_t connected)
1130 {
1131         DBG("network %p connected %d", network, connected);
1132
1133         if ((network->connecting == TRUE || network->associating == TRUE) &&
1134                                                         connected == FALSE) {
1135                 connman_network_set_error(network,
1136                                         CONNMAN_NETWORK_ERROR_CONNECT_FAIL);
1137                 __connman_network_disconnect(network);
1138         }
1139
1140         if (network->connected == connected)
1141                 return -EALREADY;
1142
1143         network->connected = connected;
1144
1145         set_connected(network);
1146
1147         return 0;
1148 }
1149
1150 /**
1151  * connman_network_get_connected:
1152  * @network: network structure
1153  *
1154  * Get network connection status
1155  */
1156 connman_bool_t connman_network_get_connected(struct connman_network *network)
1157 {
1158         return network->connected;
1159 }
1160
1161 /**
1162  * connman_network_get_associating:
1163  * @network: network structure
1164  *
1165  * Get network associating status
1166  */
1167 connman_bool_t connman_network_get_associating(struct connman_network *network)
1168 {
1169         return network->associating;
1170 }
1171
1172 int connman_network_connect_hidden(struct connman_network *network,
1173                                 char *identity, char* passphrase)
1174 {
1175         struct connman_service *service;
1176
1177         DBG("");
1178
1179         service = __connman_service_lookup_from_network(network);
1180         if (service == NULL)
1181                 return -EINVAL;
1182
1183         if (identity != NULL)
1184                 __connman_service_set_agent_identity(service, identity);
1185
1186         if (passphrase != NULL)
1187                 __connman_service_add_passphrase(service, passphrase);
1188
1189         return __connman_service_connect(service);
1190 }
1191
1192 /**
1193  * __connman_network_connect:
1194  * @network: network structure
1195  *
1196  * Connect network
1197  */
1198 int __connman_network_connect(struct connman_network *network)
1199 {
1200         int err;
1201
1202         DBG("network %p", network);
1203
1204         if (network->connected == TRUE)
1205                 return -EISCONN;
1206
1207         if (network->connecting == TRUE || network->associating == TRUE)
1208                 return -EALREADY;
1209
1210         if (network->driver == NULL)
1211                 return -EUNATCH;
1212
1213         if (network->driver->connect == NULL)
1214                 return -ENOSYS;
1215
1216         if (network->device == NULL)
1217                 return -ENODEV;
1218
1219         network->connecting = TRUE;
1220
1221         __connman_device_disconnect(network->device);
1222
1223         err = network->driver->connect(network);
1224         if (err < 0) {
1225                 if (err == -EINPROGRESS)
1226                         connman_network_set_associating(network, TRUE);
1227                 else {
1228                         network->connecting = FALSE;
1229                 }
1230
1231                 return err;
1232         }
1233
1234         network->connected = TRUE;
1235         set_connected(network);
1236
1237         return err;
1238 }
1239
1240 /**
1241  * __connman_network_disconnect:
1242  * @network: network structure
1243  *
1244  * Disconnect network
1245  */
1246 int __connman_network_disconnect(struct connman_network *network)
1247 {
1248         int err;
1249
1250         DBG("network %p", network);
1251
1252         if (network->connected == FALSE && network->connecting == FALSE &&
1253                                                 network->associating == FALSE)
1254                 return -ENOTCONN;
1255
1256         if (network->driver == NULL)
1257                 return -EUNATCH;
1258
1259         if (network->driver->disconnect == NULL)
1260                 return -ENOSYS;
1261
1262         network->connecting = FALSE;
1263
1264         err = network->driver->disconnect(network);
1265         if (err == 0) {
1266                 connman_network_set_connected(network, FALSE);
1267                 set_connected(network);
1268         }
1269
1270         return err;
1271 }
1272
1273 static int manual_ipv4_set(struct connman_network *network,
1274                                 struct connman_ipconfig *ipconfig)
1275 {
1276         struct connman_service *service;
1277         int err;
1278
1279         service = __connman_service_lookup_from_network(network);
1280         if (service == NULL)
1281                 return -EINVAL;
1282
1283         err = __connman_ipconfig_address_add(ipconfig);
1284         if (err < 0) {
1285                 connman_network_set_error(network,
1286                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
1287                 return err;
1288         }
1289
1290         return __connman_ipconfig_gateway_add(ipconfig);
1291 }
1292
1293 int __connman_network_clear_ipconfig(struct connman_network *network,
1294                                         struct connman_ipconfig *ipconfig)
1295 {
1296         struct connman_service *service;
1297         enum connman_ipconfig_method method;
1298         enum connman_ipconfig_type type;
1299
1300         service = __connman_service_lookup_from_network(network);
1301         if (service == NULL)
1302                 return -EINVAL;
1303
1304         method = __connman_ipconfig_get_method(ipconfig);
1305         type = __connman_ipconfig_get_config_type(ipconfig);
1306
1307         switch (method) {
1308         case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1309         case CONNMAN_IPCONFIG_METHOD_OFF:
1310         case CONNMAN_IPCONFIG_METHOD_FIXED:
1311         case CONNMAN_IPCONFIG_METHOD_AUTO:
1312                 return -EINVAL;
1313         case CONNMAN_IPCONFIG_METHOD_MANUAL:
1314                 __connman_ipconfig_address_remove(ipconfig);
1315                 break;
1316         case CONNMAN_IPCONFIG_METHOD_DHCP:
1317                 __connman_dhcp_stop(network);
1318                 break;
1319         }
1320
1321         if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1322                 __connman_service_ipconfig_indicate_state(service,
1323                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
1324                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1325         else if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1326                 __connman_service_ipconfig_indicate_state(service,
1327                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
1328                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1329
1330         return 0;
1331 }
1332
1333 int __connman_network_set_ipconfig(struct connman_network *network,
1334                                         struct connman_ipconfig *ipconfig_ipv4,
1335                                         struct connman_ipconfig *ipconfig_ipv6)
1336 {
1337         enum connman_ipconfig_method method;
1338         int ret;
1339
1340         if (network == NULL)
1341                 return -EINVAL;
1342
1343         if (ipconfig_ipv6) {
1344                 method = __connman_ipconfig_get_method(ipconfig_ipv6);
1345
1346                 switch (method) {
1347                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1348                 case CONNMAN_IPCONFIG_METHOD_OFF:
1349                         break;
1350                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1351                         autoconf_ipv6_set(network);
1352                         break;
1353                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1354                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1355                         ret = manual_ipv6_set(network, ipconfig_ipv6);
1356                         if (ret != 0) {
1357                                 connman_network_set_error(network,
1358                                         CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
1359                                 return ret;
1360                         }
1361                         break;
1362                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1363                         break;
1364                 }
1365         }
1366
1367         if (ipconfig_ipv4) {
1368                 method = __connman_ipconfig_get_method(ipconfig_ipv4);
1369
1370                 switch (method) {
1371                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1372                 case CONNMAN_IPCONFIG_METHOD_OFF:
1373                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1374                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1375                         return -EINVAL;
1376                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1377                         return manual_ipv4_set(network, ipconfig_ipv4);
1378                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1379                         return __connman_dhcp_start(network, dhcp_callback);
1380                 }
1381         }
1382
1383         return 0;
1384 }
1385
1386 int connman_network_set_ipaddress(struct connman_network *network,
1387                                         struct connman_ipaddress *ipaddress)
1388 {
1389         struct connman_service *service;
1390         struct connman_ipconfig *ipconfig = NULL;
1391
1392         DBG("network %p", network);
1393
1394         service = __connman_service_lookup_from_network(network);
1395         if (service == NULL)
1396                 return -EINVAL;
1397
1398         ipconfig = __connman_service_get_ipconfig(service, ipaddress->family);
1399         if (ipconfig == NULL)
1400                 return -EINVAL;
1401
1402         __connman_ipconfig_set_local(ipconfig, ipaddress->local);
1403         __connman_ipconfig_set_peer(ipconfig, ipaddress->peer);
1404         __connman_ipconfig_set_broadcast(ipconfig, ipaddress->broadcast);
1405         __connman_ipconfig_set_prefixlen(ipconfig, ipaddress->prefixlen);
1406         __connman_ipconfig_set_gateway(ipconfig, ipaddress->gateway);
1407
1408         return 0;
1409 }
1410
1411 int connman_network_set_nameservers(struct connman_network *network,
1412                                 const char *nameservers)
1413 {
1414         struct connman_service *service;
1415         char **nameservers_array;
1416         int i;
1417
1418         DBG("network %p nameservers %s", network, nameservers);
1419
1420         service = __connman_service_lookup_from_network(network);
1421         if (service == NULL)
1422                 return -EINVAL;
1423
1424         __connman_service_nameserver_clear(service);
1425
1426         if (nameservers == NULL)
1427                 return 0;
1428
1429         nameservers_array = g_strsplit(nameservers, " ", 0);
1430
1431         for (i = 0; nameservers_array[i] != NULL; i++) {
1432                 __connman_service_nameserver_append(service,
1433                                                 nameservers_array[i], FALSE);
1434         }
1435
1436         g_strfreev(nameservers_array);
1437
1438         return 0;
1439 }
1440
1441 int connman_network_set_domain(struct connman_network *network,
1442                                 const char *domain)
1443 {
1444         struct connman_service *service;
1445
1446         DBG("network %p domain %s", network, domain);
1447
1448         service = __connman_service_lookup_from_network(network);
1449         if (service == NULL)
1450                 return -EINVAL;
1451
1452         __connman_service_set_domainname(service, domain);
1453
1454         return 0;
1455 }
1456
1457 /**
1458  * connman_network_set_name:
1459  * @network: network structure
1460  * @name: name value
1461  *
1462  * Set display name value for network
1463  */
1464 int connman_network_set_name(struct connman_network *network,
1465                                                         const char *name)
1466 {
1467         DBG("network %p name %s", network, name);
1468
1469         g_free(network->name);
1470         network->name = g_strdup(name);
1471
1472         return 0;
1473 }
1474
1475 /**
1476  * connman_network_set_strength:
1477  * @network: network structure
1478  * @strength: strength value
1479  *
1480  * Set signal strength value for network
1481  */
1482
1483 int connman_network_set_strength(struct connman_network *network,
1484                                                 connman_uint8_t strength)
1485 {
1486         DBG("network %p strengh %d", network, strength);
1487
1488         network->strength = strength;
1489
1490         return 0;
1491 }
1492
1493 connman_uint8_t connman_network_get_strength(struct connman_network *network)
1494 {
1495         return network->strength;
1496 }
1497
1498 int connman_network_set_frequency(struct connman_network *network,
1499                                                 connman_uint16_t frequency)
1500 {
1501         DBG("network %p frequency %d", network, frequency);
1502
1503         network->frequency = frequency;
1504
1505         return 0;
1506 }
1507
1508 connman_uint16_t connman_network_get_frequency(struct connman_network *network)
1509 {
1510         return network->frequency;
1511 }
1512
1513 int connman_network_set_wifi_channel(struct connman_network *network,
1514                                                 connman_uint16_t channel)
1515 {
1516         DBG("network %p wifi channel %d", network, channel);
1517
1518         network->wifi.channel = channel;
1519
1520         return 0;
1521 }
1522
1523 connman_uint16_t connman_network_get_wifi_channel(struct connman_network *network)
1524 {
1525         return network->wifi.channel;
1526 }
1527
1528 /**
1529  * connman_network_set_roaming:
1530  * @network: network structure
1531  * @roaming: roaming state
1532  *
1533  * Set roaming state for network
1534  */
1535 int connman_network_set_roaming(struct connman_network *network,
1536                                                 connman_bool_t roaming)
1537 {
1538         DBG("network %p roaming %d", network, roaming);
1539
1540         network->roaming = roaming;
1541
1542         return 0;
1543 }
1544
1545 /**
1546  * connman_network_set_string:
1547  * @network: network structure
1548  * @key: unique identifier
1549  * @value: string value
1550  *
1551  * Set string value for specific key
1552  */
1553 int connman_network_set_string(struct connman_network *network,
1554                                         const char *key, const char *value)
1555 {
1556         DBG("network %p key %s value %s", network, key, value);
1557
1558         if (g_strcmp0(key, "Name") == 0)
1559                 return connman_network_set_name(network, value);
1560
1561         if (g_str_equal(key, "Path") == TRUE) {
1562                 g_free(network->path);
1563                 network->path = g_strdup(value);
1564         } else if (g_str_equal(key, "Node") == TRUE) {
1565                 g_free(network->node);
1566                 network->node = g_strdup(value);
1567         } else if (g_str_equal(key, "WiFi.Mode") == TRUE) {
1568                 g_free(network->wifi.mode);
1569                 network->wifi.mode = g_strdup(value);
1570         } else if (g_str_equal(key, "WiFi.Security") == TRUE) {
1571                 g_free(network->wifi.security);
1572                 network->wifi.security = g_strdup(value);
1573         } else if (g_str_equal(key, "WiFi.Passphrase") == TRUE) {
1574                 g_free(network->wifi.passphrase);
1575                 network->wifi.passphrase = g_strdup(value);
1576         } else if (g_str_equal(key, "WiFi.AgentPassphrase") == TRUE) {
1577                 g_free(network->wifi.agent_passphrase);
1578                 network->wifi.agent_passphrase = g_strdup(value);
1579         } else if (g_str_equal(key, "WiFi.EAP") == TRUE) {
1580                 g_free(network->wifi.eap);
1581                 network->wifi.eap = g_strdup(value);
1582         } else if (g_str_equal(key, "WiFi.Identity") == TRUE) {
1583                 g_free(network->wifi.identity);
1584                 network->wifi.identity = g_strdup(value);
1585         } else if (g_str_equal(key, "WiFi.AgentIdentity") == TRUE) {
1586                 g_free(network->wifi.agent_identity);
1587                 network->wifi.agent_identity = g_strdup(value);
1588         } else if (g_str_equal(key, "WiFi.CACertFile") == TRUE) {
1589                 g_free(network->wifi.ca_cert_path);
1590                 network->wifi.ca_cert_path = g_strdup(value);
1591         } else if (g_str_equal(key, "WiFi.ClientCertFile") == TRUE) {
1592                 g_free(network->wifi.client_cert_path);
1593                 network->wifi.client_cert_path = g_strdup(value);
1594         } else if (g_str_equal(key, "WiFi.PrivateKeyFile") == TRUE) {
1595                 g_free(network->wifi.private_key_path);
1596                 network->wifi.private_key_path = g_strdup(value);
1597         } else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase") == TRUE) {
1598                 g_free(network->wifi.private_key_passphrase);
1599                 network->wifi.private_key_passphrase = g_strdup(value);
1600         } else if (g_str_equal(key, "WiFi.Phase2") == TRUE) {
1601                 g_free(network->wifi.phase2_auth);
1602                 network->wifi.phase2_auth = g_strdup(value);
1603         } else if (g_str_equal(key, "WiFi.PinWPS") == TRUE) {
1604                 g_free(network->wifi.pin_wps);
1605                 network->wifi.pin_wps = g_strdup(value);
1606         } else {
1607                 return -EINVAL;
1608         }
1609
1610         return 0;
1611 }
1612
1613 /**
1614  * connman_network_get_string:
1615  * @network: network structure
1616  * @key: unique identifier
1617  *
1618  * Get string value for specific key
1619  */
1620 const char *connman_network_get_string(struct connman_network *network,
1621                                                         const char *key)
1622 {
1623         DBG("network %p key %s", network, key);
1624
1625         if (g_str_equal(key, "Path") == TRUE)
1626                 return network->path;
1627         else if (g_str_equal(key, "Name") == TRUE)
1628                 return network->name;
1629         else if (g_str_equal(key, "Node") == TRUE)
1630                 return network->node;
1631         else if (g_str_equal(key, "WiFi.Mode") == TRUE)
1632                 return network->wifi.mode;
1633         else if (g_str_equal(key, "WiFi.Security") == TRUE)
1634                 return network->wifi.security;
1635         else if (g_str_equal(key, "WiFi.Passphrase") == TRUE)
1636                 return network->wifi.passphrase;
1637         else if (g_str_equal(key, "WiFi.AgentPassphrase") == TRUE)
1638                 return network->wifi.agent_passphrase;
1639         else if (g_str_equal(key, "WiFi.EAP") == TRUE)
1640                 return network->wifi.eap;
1641         else if (g_str_equal(key, "WiFi.Identity") == TRUE)
1642                 return network->wifi.identity;
1643         else if (g_str_equal(key, "WiFi.AgentIdentity") == TRUE)
1644                 return network->wifi.agent_identity;
1645         else if (g_str_equal(key, "WiFi.CACertFile") == TRUE)
1646                 return network->wifi.ca_cert_path;
1647         else if (g_str_equal(key, "WiFi.ClientCertFile") == TRUE)
1648                 return network->wifi.client_cert_path;
1649         else if (g_str_equal(key, "WiFi.PrivateKeyFile") == TRUE)
1650                 return network->wifi.private_key_path;
1651         else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase") == TRUE)
1652                 return network->wifi.private_key_passphrase;
1653         else if (g_str_equal(key, "WiFi.Phase2") == TRUE)
1654                 return network->wifi.phase2_auth;
1655         else if (g_str_equal(key, "WiFi.PinWPS") == TRUE)
1656                 return network->wifi.pin_wps;
1657
1658         return NULL;
1659 }
1660
1661 /**
1662  * connman_network_set_bool:
1663  * @network: network structure
1664  * @key: unique identifier
1665  * @value: boolean value
1666  *
1667  * Set boolean value for specific key
1668  */
1669 int connman_network_set_bool(struct connman_network *network,
1670                                         const char *key, connman_bool_t value)
1671 {
1672         DBG("network %p key %s value %d", network, key, value);
1673
1674         if (g_strcmp0(key, "Roaming") == 0)
1675                 return connman_network_set_roaming(network, value);
1676         else if (g_strcmp0(key, "WiFi.WPS") == 0)
1677                 network->wifi.wps = value;
1678         else if (g_strcmp0(key, "WiFi.UseWPS") == 0)
1679                 network->wifi.use_wps = value;
1680
1681         return -EINVAL;
1682 }
1683
1684 /**
1685  * connman_network_get_bool:
1686  * @network: network structure
1687  * @key: unique identifier
1688  *
1689  * Get boolean value for specific key
1690  */
1691 connman_bool_t connman_network_get_bool(struct connman_network *network,
1692                                                         const char *key)
1693 {
1694         DBG("network %p key %s", network, key);
1695
1696         if (g_str_equal(key, "Roaming") == TRUE)
1697                 return network->roaming;
1698         else if (g_str_equal(key, "WiFi.WPS") == TRUE)
1699                 return network->wifi.wps;
1700         else if (g_str_equal(key, "WiFi.UseWPS") == TRUE)
1701                 return network->wifi.use_wps;
1702
1703         return FALSE;
1704 }
1705
1706 /**
1707  * connman_network_set_blob:
1708  * @network: network structure
1709  * @key: unique identifier
1710  * @data: blob data
1711  * @size: blob size
1712  *
1713  * Set binary blob value for specific key
1714  */
1715 int connman_network_set_blob(struct connman_network *network,
1716                         const char *key, const void *data, unsigned int size)
1717 {
1718         DBG("network %p key %s size %d", network, key, size);
1719
1720         if (g_str_equal(key, "WiFi.SSID") == TRUE) {
1721                 g_free(network->wifi.ssid);
1722                 network->wifi.ssid = g_try_malloc(size);
1723                 if (network->wifi.ssid != NULL) {
1724                         memcpy(network->wifi.ssid, data, size);
1725                         network->wifi.ssid_len = size;
1726                 } else
1727                         network->wifi.ssid_len = 0;
1728         } else {
1729                 return -EINVAL;
1730         }
1731
1732         return 0;
1733 }
1734
1735 /**
1736  * connman_network_get_blob:
1737  * @network: network structure
1738  * @key: unique identifier
1739  * @size: pointer to blob size
1740  *
1741  * Get binary blob value for specific key
1742  */
1743 const void *connman_network_get_blob(struct connman_network *network,
1744                                         const char *key, unsigned int *size)
1745 {
1746         DBG("network %p key %s", network, key);
1747
1748         if (g_str_equal(key, "WiFi.SSID") == TRUE) {
1749                 if (size != NULL)
1750                         *size = network->wifi.ssid_len;
1751                 return network->wifi.ssid;
1752         }
1753
1754         return NULL;
1755 }
1756
1757 void __connman_network_set_device(struct connman_network *network,
1758                                         struct connman_device *device)
1759 {
1760         if (network->device == device)
1761                 return;
1762
1763         if (network->device != NULL)
1764                 network_remove(network);
1765
1766         network->device = device;
1767
1768         if (network->device != NULL)
1769                 network_probe(network);
1770 }
1771
1772 /**
1773  * connman_network_get_device:
1774  * @network: network structure
1775  *
1776  * Get parent device of network
1777  */
1778 struct connman_device *connman_network_get_device(struct connman_network *network)
1779 {
1780         return network->device;
1781 }
1782
1783 /**
1784  * connman_network_get_data:
1785  * @network: network structure
1786  *
1787  * Get private network data pointer
1788  */
1789 void *connman_network_get_data(struct connman_network *network)
1790 {
1791         return network->driver_data;
1792 }
1793
1794 /**
1795  * connman_network_set_data:
1796  * @network: network structure
1797  * @data: data pointer
1798  *
1799  * Set private network data pointer
1800  */
1801 void connman_network_set_data(struct connman_network *network, void *data)
1802 {
1803         network->driver_data = data;
1804 }
1805
1806 void connman_network_update(struct connman_network *network)
1807 {
1808         switch (network->type) {
1809         case CONNMAN_NETWORK_TYPE_UNKNOWN:
1810         case CONNMAN_NETWORK_TYPE_VENDOR:
1811                 return;
1812         case CONNMAN_NETWORK_TYPE_ETHERNET:
1813         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
1814         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
1815         case CONNMAN_NETWORK_TYPE_CELLULAR:
1816         case CONNMAN_NETWORK_TYPE_WIFI:
1817         case CONNMAN_NETWORK_TYPE_WIMAX:
1818                 break;
1819         }
1820
1821         if (network->group != NULL)
1822                 __connman_service_update_from_network(network);
1823 }
1824
1825 int __connman_network_init(void)
1826 {
1827         DBG("");
1828
1829         return 0;
1830 }
1831
1832 void __connman_network_cleanup(void)
1833 {
1834         DBG("");
1835 }