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