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