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