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