Added some logs for debugging
[platform/upstream/connman.git] / src / network.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2014  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 /*
32  * How many times to send RS with the purpose of
33  * refreshing RDNSS entries before they actually expire.
34  * With a value of 1, one RS will be sent, with no retries.
35  */
36 #define RS_REFRESH_COUNT        1
37
38 /*
39  * Value in seconds to wait for RA after RS was sent.
40  * After this time elapsed, we can send another RS.
41  */
42 #define RS_REFRESH_TIMEOUT      3
43
44 #if defined TIZEN_EXT
45 #define WIFI_ENCYPTION_MODE_LEN_MAX 6
46 #define WIFI_BSSID_LEN_MAX 6
47 #endif
48
49 static GSList *network_list = NULL;
50 static GSList *driver_list = NULL;
51
52 struct connman_network {
53         int refcount;
54         enum connman_network_type type;
55         bool available;
56         bool connected;
57         bool roaming;
58         uint8_t strength;
59         uint16_t frequency;
60         char *identifier;
61         char *name;
62         char *node;
63         char *group;
64         char *path;
65         int index;
66         int router_solicit_count;
67         int router_solicit_refresh_count;
68
69         struct connman_network_driver *driver;
70         void *driver_data;
71
72         bool connecting;
73         bool associating;
74
75         struct connman_device *device;
76
77         struct {
78                 void *ssid;
79                 int ssid_len;
80                 char *mode;
81                 unsigned short channel;
82                 char *security;
83                 char *passphrase;
84                 char *eap;
85                 char *identity;
86                 char *agent_identity;
87                 char *ca_cert_path;
88                 char *client_cert_path;
89                 char *private_key_path;
90                 char *private_key_passphrase;
91                 char *phase2_auth;
92                 bool wps;
93                 bool use_wps;
94                 char *pin_wps;
95 #if defined TIZEN_EXT
96                 char encryption_mode[WIFI_ENCYPTION_MODE_LEN_MAX];
97                 unsigned char bssid[WIFI_BSSID_LEN_MAX];
98                 unsigned int maxrate;
99                 unsigned int isHS20AP;
100                 unsigned int keymgmt;
101                 char *keymgmt_type;
102                 bool rsn_mode;
103                 int disconnect_reason;
104 #endif
105         } wifi;
106
107 #if defined TIZEN_EXT
108         /* Multiple APN services and a default APN which a user selected */
109         bool default_internet;
110 #endif
111
112 };
113
114 static void autoconf_ipv6_set(struct connman_network *network);
115
116 static const char *type2string(enum connman_network_type type)
117 {
118         switch (type) {
119         case CONNMAN_NETWORK_TYPE_UNKNOWN:
120         case CONNMAN_NETWORK_TYPE_VENDOR:
121                 break;
122         case CONNMAN_NETWORK_TYPE_ETHERNET:
123                 return "ethernet";
124         case CONNMAN_NETWORK_TYPE_GADGET:
125                 return "gadget";
126         case CONNMAN_NETWORK_TYPE_WIFI:
127                 return "wifi";
128         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
129         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
130                 return "bluetooth";
131         case CONNMAN_NETWORK_TYPE_CELLULAR:
132                 return "cellular";
133         }
134
135         return NULL;
136 }
137
138 static bool match_driver(struct connman_network *network,
139                                         struct connman_network_driver *driver)
140 {
141         if (network->type == driver->type ||
142                         driver->type == CONNMAN_NETWORK_TYPE_UNKNOWN)
143                 return true;
144
145         return false;
146 }
147
148 static void set_configuration(struct connman_network *network,
149                         enum connman_ipconfig_type type)
150 {
151         struct connman_service *service;
152
153         DBG("network %p", network);
154
155         if (!network->device)
156                 return;
157
158         __connman_device_set_network(network->device, network);
159
160         connman_device_set_disconnected(network->device, false);
161
162         service = connman_service_lookup_from_network(network);
163         __connman_service_ipconfig_indicate_state(service,
164                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
165                                         type);
166 }
167
168 static void dhcp_success(struct connman_network *network)
169 {
170         struct connman_service *service;
171         struct connman_ipconfig *ipconfig_ipv4;
172         int err;
173
174         service = connman_service_lookup_from_network(network);
175         if (!service)
176                 goto err;
177
178         ipconfig_ipv4 = __connman_service_get_ip4config(service);
179
180         DBG("lease acquired for ipconfig %p", ipconfig_ipv4);
181
182         if (!ipconfig_ipv4)
183                 return;
184
185         err = __connman_ipconfig_address_add(ipconfig_ipv4);
186         if (err < 0)
187                 goto err;
188
189 #if defined TIZEN_EXT
190         err = __connman_ipconfig_gateway_add(ipconfig_ipv4, service);
191 #else
192         err = __connman_ipconfig_gateway_add(ipconfig_ipv4);
193 #endif
194         if (err < 0)
195                 goto err;
196
197         return;
198
199 err:
200         connman_network_set_error(network,
201                                 CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
202 }
203
204 static void dhcp_failure(struct connman_network *network)
205 {
206         struct connman_service *service;
207         struct connman_ipconfig *ipconfig_ipv4;
208
209         service = connman_service_lookup_from_network(network);
210         if (!service)
211                 return;
212
213         ipconfig_ipv4 = __connman_service_get_ip4config(service);
214
215         DBG("lease lost for ipconfig %p", ipconfig_ipv4);
216
217         if (!ipconfig_ipv4)
218                 return;
219
220         __connman_ipconfig_address_remove(ipconfig_ipv4);
221         __connman_ipconfig_gateway_remove(ipconfig_ipv4);
222 }
223
224 static void dhcp_callback(struct connman_ipconfig *ipconfig,
225                         struct connman_network *network,
226                         bool success, gpointer data)
227 {
228 #if defined TIZEN_EXT
229         struct connman_service *service;
230         struct connman_ipconfig *ipconfig_ipv6;
231 #endif
232
233         network->connecting = false;
234
235         if (success)
236                 dhcp_success(network);
237         else
238                 dhcp_failure(network);
239
240 #if defined TIZEN_EXT
241         service = connman_service_lookup_from_network(network);
242         ipconfig_ipv6 = __connman_service_get_ip6config(service);
243         if (__connman_ipconfig_get_method(ipconfig_ipv6) == CONNMAN_IPCONFIG_METHOD_AUTO) {
244                 DBG("IPv6 autoconf start");
245                 set_configuration(network, CONNMAN_IPCONFIG_TYPE_IPV6);
246                 autoconf_ipv6_set(network);
247         }
248 #endif
249 }
250
251 static int set_connected_manual(struct connman_network *network)
252 {
253         int err = 0;
254         struct connman_service *service;
255         struct connman_ipconfig *ipconfig;
256
257         DBG("network %p", network);
258
259         network->connecting = false;
260
261         service = connman_service_lookup_from_network(network);
262
263         ipconfig = __connman_service_get_ip4config(service);
264
265         if (!__connman_ipconfig_get_local(ipconfig))
266                 __connman_service_read_ip4config(service);
267
268         err = __connman_ipconfig_address_add(ipconfig);
269         if (err < 0)
270                 goto err;
271
272 #if defined TIZEN_EXT
273         err = __connman_ipconfig_gateway_add(ipconfig, service);
274 #else
275         err = __connman_ipconfig_gateway_add(ipconfig);
276 #endif
277         if (err < 0)
278                 goto err;
279
280 err:
281         return err;
282 }
283
284 static int set_connected_dhcp(struct connman_network *network)
285 {
286         struct connman_service *service;
287         struct connman_ipconfig *ipconfig_ipv4;
288         int err;
289
290         DBG("network %p", network);
291
292         service = connman_service_lookup_from_network(network);
293         ipconfig_ipv4 = __connman_service_get_ip4config(service);
294
295         err = __connman_dhcp_start(ipconfig_ipv4, network,
296                                                         dhcp_callback, NULL);
297         if (err < 0) {
298                 connman_error("Can not request DHCP lease");
299                 return err;
300         }
301
302         return 0;
303 }
304
305 static int manual_ipv6_set(struct connman_network *network,
306                                 struct connman_ipconfig *ipconfig_ipv6)
307 {
308         struct connman_service *service;
309         int err;
310
311         DBG("network %p ipv6 %p", network, ipconfig_ipv6);
312
313         service = connman_service_lookup_from_network(network);
314         if (!service)
315                 return -EINVAL;
316
317         if (!__connman_ipconfig_get_local(ipconfig_ipv6))
318                 __connman_service_read_ip6config(service);
319
320         __connman_ipconfig_enable_ipv6(ipconfig_ipv6);
321
322         err = __connman_ipconfig_address_add(ipconfig_ipv6);
323         if (err < 0) {
324                 connman_network_set_error(network,
325                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
326                 return err;
327         }
328
329 #if defined TIZEN_EXT
330         err = __connman_ipconfig_gateway_add(ipconfig_ipv6, service);
331 #else
332         err = __connman_ipconfig_gateway_add(ipconfig_ipv6);
333 #endif
334         if (err < 0)
335                 return err;
336
337         __connman_connection_gateway_activate(service,
338                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
339
340         __connman_device_set_network(network->device, network);
341
342         connman_device_set_disconnected(network->device, false);
343
344         connman_network_set_associating(network, false);
345
346         network->connecting = false;
347
348         return 0;
349 }
350
351 static void stop_dhcpv6(struct connman_network *network)
352 {
353         network->connecting = false;
354
355         __connman_dhcpv6_stop(network);
356 }
357
358 static void dhcpv6_release_callback(struct connman_network *network,
359                                 enum __connman_dhcpv6_status status,
360                                 gpointer data)
361 {
362         DBG("status %d", status);
363
364         stop_dhcpv6(network);
365 }
366
367 static void release_dhcpv6(struct connman_network *network)
368 {
369         __connman_dhcpv6_start_release(network, dhcpv6_release_callback);
370         stop_dhcpv6(network);
371 }
372
373 static void dhcpv6_info_callback(struct connman_network *network,
374                                 enum __connman_dhcpv6_status status,
375                                 gpointer data)
376 {
377         DBG("status %d", status);
378
379         stop_dhcpv6(network);
380 }
381
382 static int dhcpv6_set_addresses(struct connman_network *network)
383 {
384         struct connman_service *service;
385         struct connman_ipconfig *ipconfig_ipv6;
386         int err = -EINVAL;
387
388         service = connman_service_lookup_from_network(network);
389         if (!service)
390                 goto err;
391
392         network->connecting = false;
393
394         ipconfig_ipv6 = __connman_service_get_ip6config(service);
395         err = __connman_ipconfig_address_add(ipconfig_ipv6);
396         if (err < 0)
397                 goto err;
398
399         return 0;
400
401 err:
402         connman_network_set_error(network,
403                                 CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
404         return err;
405 }
406
407 static void dhcpv6_callback(struct connman_network *network,
408                         enum __connman_dhcpv6_status status, gpointer data);
409
410 /*
411  * Have a separate callback for renew so that we do not do autoconf
412  * in wrong phase as the dhcpv6_callback() is also called when doing
413  * DHCPv6 solicitation.
414  */
415 static void dhcpv6_renew_callback(struct connman_network *network,
416                                 enum __connman_dhcpv6_status status,
417                                 gpointer data)
418 {
419         switch (status) {
420         case CONNMAN_DHCPV6_STATUS_SUCCEED:
421                 dhcpv6_callback(network, status, data);
422                 break;
423         case CONNMAN_DHCPV6_STATUS_FAIL:
424         case CONNMAN_DHCPV6_STATUS_RESTART:
425                 stop_dhcpv6(network);
426
427                 /* restart and do solicit again. */
428                 autoconf_ipv6_set(network);
429                 break;
430         }
431 }
432
433 static void dhcpv6_callback(struct connman_network *network,
434                         enum __connman_dhcpv6_status status, gpointer data)
435 {
436         DBG("status %d", status);
437
438         /* Start the renew process if necessary */
439         if (status == CONNMAN_DHCPV6_STATUS_SUCCEED) {
440
441                 if (dhcpv6_set_addresses(network) < 0) {
442                         stop_dhcpv6(network);
443                         return;
444                 }
445
446                 if (__connman_dhcpv6_start_renew(network,
447                                         dhcpv6_renew_callback) == -ETIMEDOUT)
448                         dhcpv6_renew_callback(network,
449                                                 CONNMAN_DHCPV6_STATUS_FAIL,
450                                                 data);
451
452         } else if (status == CONNMAN_DHCPV6_STATUS_RESTART) {
453                 stop_dhcpv6(network);
454                 autoconf_ipv6_set(network);
455         } else
456                 stop_dhcpv6(network);
457 }
458
459 static void check_dhcpv6(struct nd_router_advert *reply,
460                         unsigned int length, void *user_data)
461 {
462         struct connman_network *network = user_data;
463         struct connman_service *service;
464         GSList *prefixes;
465
466         DBG("reply %p", reply);
467
468         if (!reply) {
469                 /*
470                  * Router solicitation message seem to get lost easily so
471                  * try to send it again.
472                  */
473                 if (network->router_solicit_count > 0) {
474                         DBG("re-send router solicitation %d",
475                                                 network->router_solicit_count);
476                         network->router_solicit_count--;
477                         __connman_inet_ipv6_send_rs(network->index, 1,
478                                                 check_dhcpv6, network);
479                         return;
480                 }
481 #if defined TIZEN_EXT
482                 DBG("RA message is not received from server in reply of RS.");
483 #endif
484                 connman_network_unref(network);
485                 return;
486         }
487
488         network->router_solicit_count = 0;
489
490         /*
491          * If we were disconnected while waiting router advertisement,
492          * we just quit and do not start DHCPv6
493          */
494         if (!network->connected) {
495                 connman_network_unref(network);
496 #if defined TIZEN_EXT
497                 DBG("Network is not connected");
498 #endif
499                 return;
500         }
501
502         prefixes = __connman_inet_ipv6_get_prefixes(reply, length);
503
504         /*
505          * If IPv6 config is missing from service, then create it.
506          * The ipconfig might be missing if we got a rtnl message
507          * that disabled IPv6 config and thus removed it. This
508          * can happen if we are switching from one service to
509          * another in the same interface. The only way to get IPv6
510          * config back is to re-create it here.
511          */
512         service = connman_service_lookup_from_network(network);
513         if (service) {
514                 connman_service_create_ip6config(service, network->index);
515
516                 connman_network_set_associating(network, false);
517
518                 __connman_service_ipconfig_indicate_state(service,
519                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
520                                         CONNMAN_IPCONFIG_TYPE_IPV6);
521         }
522
523         /*
524          * We do stateful/stateless DHCPv6 if router advertisement says so.
525          */
526         if (reply->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) {
527 #if defined TIZEN_EXT
528                 DBG("IPv6 ND_RA_FLAG_MANAGED");
529 #endif
530                 __connman_dhcpv6_start(network, prefixes, dhcpv6_callback);
531         } else {
532                 if (reply->nd_ra_flags_reserved & ND_RA_FLAG_OTHER)
533 #if defined TIZEN_EXT
534                 {
535                         DBG("IPv6 ND_RA_FLAG_OTHER");
536 #endif
537                         __connman_dhcpv6_start_info(network,
538                                                         dhcpv6_info_callback);
539 #if defined TIZEN_EXT
540                 }
541 #endif
542
543                 g_slist_free_full(prefixes, g_free);
544                 network->connecting = false;
545         }
546
547         connman_network_unref(network);
548 }
549
550 static void receive_refresh_rs_reply(struct nd_router_advert *reply,
551                 unsigned int length, void *user_data)
552 {
553         struct connman_network *network = user_data;
554
555         DBG("reply %p", reply);
556
557         if (!reply) {
558                 /*
559                  * Router solicitation message seem to get lost easily so
560                  * try to send it again.
561                  */
562                 if (network->router_solicit_refresh_count > 1) {
563                         network->router_solicit_refresh_count--;
564                         DBG("re-send router solicitation %d",
565                                         network->router_solicit_refresh_count);
566                         __connman_inet_ipv6_send_rs(network->index,
567                                         RS_REFRESH_TIMEOUT,
568                                         receive_refresh_rs_reply,
569                                         network);
570                         return;
571                 }
572         }
573
574         /* RS refresh not in progress anymore */
575         network->router_solicit_refresh_count = 0;
576
577         connman_network_unref(network);
578         return;
579 }
580
581 int __connman_network_refresh_rs_ipv6(struct connman_network *network,
582                                         int index)
583 {
584         int ret = 0;
585
586         DBG("network %p index %d", network, index);
587
588         /* Send only one RS for all RDNSS entries which are about to expire */
589         if (network->router_solicit_refresh_count > 0) {
590                 DBG("RS refresh already started");
591                 return 0;
592         }
593
594         network->router_solicit_refresh_count = RS_REFRESH_COUNT;
595
596         connman_network_ref(network);
597
598         ret = __connman_inet_ipv6_send_rs(index, RS_REFRESH_TIMEOUT,
599                         receive_refresh_rs_reply, network);
600         return ret;
601 }
602
603 static void autoconf_ipv6_set(struct connman_network *network)
604 {
605         struct connman_service *service;
606         struct connman_ipconfig *ipconfig;
607         int index;
608
609         DBG("network %p", network);
610
611         if (network->router_solicit_count > 0) {
612                 /*
613                  * The autoconfiguration is already pending and we have sent
614                  * router solicitation messages and are now waiting answers.
615                  * There is no need to continue any further.
616                  */
617                 DBG("autoconfiguration already started");
618                 return;
619         }
620
621         __connman_device_set_network(network->device, network);
622
623         connman_device_set_disconnected(network->device, false);
624
625 #if defined TIZEN_EXT
626         if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR)
627                 return;
628 #endif
629
630         service = connman_service_lookup_from_network(network);
631         if (!service)
632                 return;
633
634         ipconfig = __connman_service_get_ip6config(service);
635         if (!ipconfig)
636                 return;
637
638         __connman_ipconfig_enable_ipv6(ipconfig);
639
640         __connman_ipconfig_address_remove(ipconfig);
641
642         index = __connman_ipconfig_get_index(ipconfig);
643
644         connman_network_ref(network);
645
646         /* Try to get stateless DHCPv6 information, RFC 3736 */
647         network->router_solicit_count = 3;
648         __connman_inet_ipv6_send_rs(index, 1, check_dhcpv6, network);
649 }
650
651 static void set_connected(struct connman_network *network)
652 {
653         struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
654         struct connman_service *service;
655
656         if (network->connected)
657                 return;
658
659         connman_network_set_associating(network, false);
660
661         network->connected = true;
662
663         service = connman_service_lookup_from_network(network);
664
665         ipconfig_ipv4 = __connman_service_get_ip4config(service);
666         ipconfig_ipv6 = __connman_service_get_ip6config(service);
667
668         DBG("service %p ipv4 %p ipv6 %p", service, ipconfig_ipv4,
669                 ipconfig_ipv6);
670
671         __connman_network_enable_ipconfig(network, ipconfig_ipv4);
672         __connman_network_enable_ipconfig(network, ipconfig_ipv6);
673 }
674
675 static void set_disconnected(struct connman_network *network)
676 {
677         struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
678         enum connman_ipconfig_method ipv4_method, ipv6_method;
679         enum connman_service_state state;
680         struct connman_service *service;
681
682         service = connman_service_lookup_from_network(network);
683
684         ipconfig_ipv4 = __connman_service_get_ip4config(service);
685         ipconfig_ipv6 = __connman_service_get_ip6config(service);
686
687         DBG("service %p ipv4 %p ipv6 %p", service, ipconfig_ipv4,
688                 ipconfig_ipv6);
689
690         ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4);
691         ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6);
692
693         DBG("method ipv4 %d ipv6 %d", ipv4_method, ipv6_method);
694
695         /*
696          * Resetting solicit count here will prevent the RS resend loop
697          * from sending packets in check_dhcpv6()
698          */
699         network->router_solicit_count = 0;
700
701         __connman_device_set_network(network->device, NULL);
702
703         if (network->connected) {
704                 switch (ipv6_method) {
705                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
706                 case CONNMAN_IPCONFIG_METHOD_OFF:
707                 case CONNMAN_IPCONFIG_METHOD_FIXED:
708                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
709                         break;
710                 case CONNMAN_IPCONFIG_METHOD_DHCP:
711                 case CONNMAN_IPCONFIG_METHOD_AUTO:
712                         release_dhcpv6(network);
713                         break;
714                 }
715
716                 switch (ipv4_method) {
717                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
718                 case CONNMAN_IPCONFIG_METHOD_OFF:
719                 case CONNMAN_IPCONFIG_METHOD_AUTO:
720                 case CONNMAN_IPCONFIG_METHOD_FIXED:
721                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
722                         break;
723                 case CONNMAN_IPCONFIG_METHOD_DHCP:
724                         __connman_dhcp_stop(ipconfig_ipv4);
725                         break;
726                 }
727         }
728
729         /*
730          * We only set the disconnect state if we were not in idle
731          * or in failure. It does not make sense to go to disconnect
732          * state if we were not connected.
733          */
734         state = __connman_service_ipconfig_get_state(service,
735                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
736         if (state != CONNMAN_SERVICE_STATE_IDLE &&
737                         state != CONNMAN_SERVICE_STATE_FAILURE)
738                 __connman_service_ipconfig_indicate_state(service,
739                                         CONNMAN_SERVICE_STATE_DISCONNECT,
740                                         CONNMAN_IPCONFIG_TYPE_IPV4);
741
742         state = __connman_service_ipconfig_get_state(service,
743                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
744         if (state != CONNMAN_SERVICE_STATE_IDLE &&
745                                 state != CONNMAN_SERVICE_STATE_FAILURE)
746                 __connman_service_ipconfig_indicate_state(service,
747                                         CONNMAN_SERVICE_STATE_DISCONNECT,
748                                         CONNMAN_IPCONFIG_TYPE_IPV6);
749
750         if (network->connected) {
751 #if defined TIZEN_EXT
752                 /**
753                  * Do not remove gateway and its address,
754                  * if there are connected profiles that use same interface (multiple PDN)
755                  */
756                 if (connman_service_get_type(service) != CONNMAN_SERVICE_TYPE_CELLULAR ||
757                                 __connman_service_get_connected_count_of_iface(service) <= 0) {
758 #endif
759                 __connman_connection_gateway_remove(service,
760                                                 CONNMAN_IPCONFIG_TYPE_ALL);
761
762                 __connman_ipconfig_address_unset(ipconfig_ipv4);
763                 __connman_ipconfig_address_unset(ipconfig_ipv6);
764 #if defined TIZEN_EXT
765                 }
766 #endif
767                 /*
768                  * Special handling for IPv6 autoconfigured address.
769                  * The simplest way to remove autoconfigured routes is to
770                  * disable IPv6 temporarily so that kernel will do the cleanup
771                  * automagically.
772                  */
773                 if (ipv6_method == CONNMAN_IPCONFIG_METHOD_AUTO) {
774                         __connman_ipconfig_disable_ipv6(ipconfig_ipv6);
775                         __connman_ipconfig_enable_ipv6(ipconfig_ipv6);
776                 }
777         }
778
779         __connman_service_ipconfig_indicate_state(service,
780                                                 CONNMAN_SERVICE_STATE_IDLE,
781                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
782
783         __connman_service_ipconfig_indicate_state(service,
784                                                 CONNMAN_SERVICE_STATE_IDLE,
785                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
786
787         network->connecting = false;
788         network->connected = false;
789
790         connman_network_set_associating(network, false);
791 }
792
793
794
795 static int network_probe(struct connman_network *network)
796 {
797         GSList *list;
798         struct connman_network_driver *driver = NULL;
799
800         DBG("network %p name %s", network, network->name);
801
802         if (network->driver)
803                 return -EALREADY;
804
805         for (list = driver_list; list; list = list->next) {
806                 driver = list->data;
807
808                 if (!match_driver(network, driver)) {
809                         driver = NULL;
810                         continue;
811                 }
812
813                 DBG("driver %p name %s", driver, driver->name);
814
815                 if (driver->probe(network) == 0)
816                         break;
817
818                 driver = NULL;
819         }
820
821         if (!driver)
822                 return -ENODEV;
823
824         if (!network->group)
825                 return -EINVAL;
826
827         switch (network->type) {
828         case CONNMAN_NETWORK_TYPE_UNKNOWN:
829         case CONNMAN_NETWORK_TYPE_VENDOR:
830                 return 0;
831         case CONNMAN_NETWORK_TYPE_ETHERNET:
832         case CONNMAN_NETWORK_TYPE_GADGET:
833         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
834         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
835         case CONNMAN_NETWORK_TYPE_CELLULAR:
836         case CONNMAN_NETWORK_TYPE_WIFI:
837                 network->driver = driver;
838                 if (!__connman_service_create_from_network(network)) {
839                         network->driver = NULL;
840                         return -EINVAL;
841                 }
842         }
843
844         return 0;
845 }
846
847 static void network_remove(struct connman_network *network)
848 {
849         DBG("network %p name %s", network, network->name);
850
851         if (!network->driver)
852                 return;
853
854         if (network->connected)
855                 set_disconnected(network);
856
857         switch (network->type) {
858         case CONNMAN_NETWORK_TYPE_UNKNOWN:
859         case CONNMAN_NETWORK_TYPE_VENDOR:
860                 break;
861         case CONNMAN_NETWORK_TYPE_ETHERNET:
862         case CONNMAN_NETWORK_TYPE_GADGET:
863         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
864         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
865         case CONNMAN_NETWORK_TYPE_CELLULAR:
866         case CONNMAN_NETWORK_TYPE_WIFI:
867                 if (network->group) {
868                         __connman_service_remove_from_network(network);
869
870                         g_free(network->group);
871                         network->group = NULL;
872                 }
873                 break;
874         }
875
876         if (network->driver->remove)
877                 network->driver->remove(network);
878
879         network->driver = NULL;
880 }
881
882 static void probe_driver(struct connman_network_driver *driver)
883 {
884         GSList *list;
885
886         DBG("driver %p name %s", driver, driver->name);
887
888         for (list = network_list; list; list = list->next) {
889                 struct connman_network *network = list->data;
890
891                 if (network->driver)
892                         continue;
893
894                 if (driver->type != network->type)
895                         continue;
896
897                 if (driver->probe(network) < 0)
898                         continue;
899
900                 network->driver = driver;
901         }
902 }
903
904 static void remove_driver(struct connman_network_driver *driver)
905 {
906         GSList *list;
907
908         DBG("driver %p name %s", driver, driver->name);
909
910         for (list = network_list; list; list = list->next) {
911                 struct connman_network *network = list->data;
912
913                 if (network->driver == driver)
914                         network_remove(network);
915         }
916 }
917
918 static gint compare_priority(gconstpointer a, gconstpointer b)
919 {
920         const struct connman_network_driver *driver1 = a;
921         const struct connman_network_driver *driver2 = b;
922
923         return driver2->priority - driver1->priority;
924 }
925
926 /**
927  * connman_network_driver_register:
928  * @driver: network driver definition
929  *
930  * Register a new network driver
931  *
932  * Returns: %0 on success
933  */
934 int connman_network_driver_register(struct connman_network_driver *driver)
935 {
936         DBG("driver %p name %s", driver, driver->name);
937
938         driver_list = g_slist_insert_sorted(driver_list, driver,
939                                                         compare_priority);
940
941         probe_driver(driver);
942
943         return 0;
944 }
945
946 /**
947  * connman_network_driver_unregister:
948  * @driver: network driver definition
949  *
950  * Remove a previously registered network driver
951  */
952 void connman_network_driver_unregister(struct connman_network_driver *driver)
953 {
954         DBG("driver %p name %s", driver, driver->name);
955
956         driver_list = g_slist_remove(driver_list, driver);
957
958         remove_driver(driver);
959 }
960
961 static void network_destruct(struct connman_network *network)
962 {
963         DBG("network %p name %s", network, network->name);
964
965         g_free(network->wifi.ssid);
966         g_free(network->wifi.mode);
967         g_free(network->wifi.security);
968         g_free(network->wifi.passphrase);
969         g_free(network->wifi.eap);
970         g_free(network->wifi.identity);
971         g_free(network->wifi.agent_identity);
972         g_free(network->wifi.ca_cert_path);
973         g_free(network->wifi.client_cert_path);
974         g_free(network->wifi.private_key_path);
975         g_free(network->wifi.private_key_passphrase);
976         g_free(network->wifi.phase2_auth);
977         g_free(network->wifi.pin_wps);
978
979         g_free(network->path);
980         g_free(network->group);
981         g_free(network->node);
982         g_free(network->name);
983         g_free(network->identifier);
984
985         network->device = NULL;
986
987         g_free(network);
988 }
989
990 /**
991  * connman_network_create:
992  * @identifier: network identifier (for example an unqiue name)
993  *
994  * Allocate a new network and assign the #identifier to it.
995  *
996  * Returns: a newly-allocated #connman_network structure
997  */
998 struct connman_network *connman_network_create(const char *identifier,
999                                                 enum connman_network_type type)
1000 {
1001         struct connman_network *network;
1002         char *ident;
1003
1004         DBG("identifier %s type %d", identifier, type);
1005
1006         network = g_try_new0(struct connman_network, 1);
1007         if (!network)
1008                 return NULL;
1009
1010         DBG("network %p", network);
1011
1012         network->refcount = 1;
1013
1014         ident = g_strdup(identifier);
1015
1016         if (!ident) {
1017                 g_free(network);
1018                 return NULL;
1019         }
1020
1021         network->type       = type;
1022         network->identifier = ident;
1023
1024         network_list = g_slist_prepend(network_list, network);
1025
1026         return network;
1027 }
1028
1029 /**
1030  * connman_network_ref:
1031  * @network: network structure
1032  *
1033  * Increase reference counter of  network
1034  */
1035 struct connman_network *
1036 connman_network_ref_debug(struct connman_network *network,
1037                         const char *file, int line, const char *caller)
1038 {
1039         DBG("%p name %s ref %d by %s:%d:%s()", network, network->name,
1040                 network->refcount + 1, file, line, caller);
1041
1042         __sync_fetch_and_add(&network->refcount, 1);
1043
1044         return network;
1045 }
1046
1047 /**
1048  * connman_network_unref:
1049  * @network: network structure
1050  *
1051  * Decrease reference counter of network
1052  */
1053 void connman_network_unref_debug(struct connman_network *network,
1054                                 const char *file, int line, const char *caller)
1055 {
1056         DBG("%p name %s ref %d by %s:%d:%s()", network, network->name,
1057                 network->refcount - 1, file, line, caller);
1058
1059         if (__sync_fetch_and_sub(&network->refcount, 1) != 1)
1060                 return;
1061
1062         network_list = g_slist_remove(network_list, network);
1063
1064         network_destruct(network);
1065 }
1066
1067 const char *__connman_network_get_type(struct connman_network *network)
1068 {
1069         return type2string(network->type);
1070 }
1071
1072 /**
1073  * connman_network_get_type:
1074  * @network: network structure
1075  *
1076  * Get type of network
1077  */
1078 enum connman_network_type connman_network_get_type(
1079                                 struct connman_network *network)
1080 {
1081         return network->type;
1082 }
1083
1084 /**
1085  * connman_network_get_identifier:
1086  * @network: network structure
1087  *
1088  * Get identifier of network
1089  */
1090 const char *connman_network_get_identifier(struct connman_network *network)
1091 {
1092         return network->identifier;
1093 }
1094
1095 /**
1096  * connman_network_set_index:
1097  * @network: network structure
1098  * @index: index number
1099  *
1100  * Set index number of network
1101  */
1102 void connman_network_set_index(struct connman_network *network, int index)
1103 {
1104         struct connman_service *service;
1105         struct connman_ipconfig *ipconfig;
1106
1107         service = connman_service_lookup_from_network(network);
1108         if (!service)
1109                 goto done;
1110
1111         ipconfig = __connman_service_get_ip4config(service);
1112         if (ipconfig) {
1113                 __connman_ipconfig_set_index(ipconfig, index);
1114
1115                 DBG("index %d service %p ip4config %p", network->index,
1116                         service, ipconfig);
1117         }
1118
1119         ipconfig = __connman_service_get_ip6config(service);
1120         if (ipconfig) {
1121                 __connman_ipconfig_set_index(ipconfig, index);
1122
1123                 DBG("index %d service %p ip6config %p", network->index,
1124                         service, ipconfig);
1125         }
1126
1127 done:
1128         network->index = index;
1129 }
1130
1131 /**
1132  * connman_network_get_index:
1133  * @network: network structure
1134  *
1135  * Get index number of network
1136  */
1137 int connman_network_get_index(struct connman_network *network)
1138 {
1139         return network->index;
1140 }
1141
1142 /**
1143  * connman_network_set_group:
1144  * @network: network structure
1145  * @group: group name
1146  *
1147  * Set group name for automatic clustering
1148  */
1149 void connman_network_set_group(struct connman_network *network,
1150                                                         const char *group)
1151 {
1152         switch (network->type) {
1153         case CONNMAN_NETWORK_TYPE_UNKNOWN:
1154         case CONNMAN_NETWORK_TYPE_VENDOR:
1155                 return;
1156         case CONNMAN_NETWORK_TYPE_ETHERNET:
1157         case CONNMAN_NETWORK_TYPE_GADGET:
1158         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
1159         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
1160         case CONNMAN_NETWORK_TYPE_CELLULAR:
1161         case CONNMAN_NETWORK_TYPE_WIFI:
1162                 break;
1163         }
1164
1165         if (g_strcmp0(network->group, group) == 0) {
1166                 if (group)
1167                         __connman_service_update_from_network(network);
1168                 return;
1169         }
1170
1171         if (network->group) {
1172                 __connman_service_remove_from_network(network);
1173
1174                 g_free(network->group);
1175         }
1176
1177         network->group = g_strdup(group);
1178
1179         if (network->group)
1180                 network_probe(network);
1181 }
1182
1183 /**
1184  * connman_network_get_group:
1185  * @network: network structure
1186  *
1187  * Get group name for automatic clustering
1188  */
1189 const char *connman_network_get_group(struct connman_network *network)
1190 {
1191         return network->group;
1192 }
1193
1194 const char *__connman_network_get_ident(struct connman_network *network)
1195 {
1196         if (!network->device)
1197                 return NULL;
1198
1199         return connman_device_get_ident(network->device);
1200 }
1201
1202 bool __connman_network_get_weakness(struct connman_network *network)
1203 {
1204         switch (network->type) {
1205         case CONNMAN_NETWORK_TYPE_UNKNOWN:
1206         case CONNMAN_NETWORK_TYPE_VENDOR:
1207         case CONNMAN_NETWORK_TYPE_ETHERNET:
1208         case CONNMAN_NETWORK_TYPE_GADGET:
1209         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
1210         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
1211         case CONNMAN_NETWORK_TYPE_CELLULAR:
1212                 break;
1213         case CONNMAN_NETWORK_TYPE_WIFI:
1214                 if (network->strength > 0 && network->strength < 20)
1215                         return true;
1216                 break;
1217         }
1218
1219         return false;
1220 }
1221
1222 #if defined TIZEN_EXT
1223 void connman_network_set_connecting(struct connman_network *network)
1224 {
1225         DBG("set network connecting true");
1226         network->connecting = TRUE;
1227         return;
1228 }
1229 #endif
1230
1231 bool connman_network_get_connecting(struct connman_network *network)
1232 {
1233         return network->connecting;
1234 }
1235
1236 /**
1237  * connman_network_set_available:
1238  * @network: network structure
1239  * @available: availability state
1240  *
1241  * Change availability state of network (in range)
1242  */
1243 int connman_network_set_available(struct connman_network *network,
1244                                                 bool available)
1245 {
1246 #if !defined TIZEN_EXT
1247         DBG("network %p available %d", network, available);
1248 #endif
1249
1250         if (network->available == available)
1251                 return -EALREADY;
1252
1253         network->available = available;
1254
1255         return 0;
1256 }
1257
1258 /**
1259  * connman_network_get_available:
1260  * @network: network structure
1261  *
1262  * Get network available setting
1263  */
1264 bool connman_network_get_available(struct connman_network *network)
1265 {
1266         return network->available;
1267 }
1268
1269 #if defined TIZEN_EXT
1270 void connman_network_clear_associating(struct connman_network *network)
1271 {
1272         struct connman_service *service;
1273         enum connman_service_state state;
1274
1275         DBG("network %p", network);
1276
1277         network->connecting = FALSE;
1278         network->associating = FALSE;
1279
1280         service = connman_service_lookup_from_network(network);
1281         if (!service)
1282                 return;
1283
1284         state = __connman_service_ipconfig_get_state(service,
1285                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1286         if (state != CONNMAN_SERVICE_STATE_IDLE &&
1287                         state != CONNMAN_SERVICE_STATE_FAILURE)
1288                 __connman_service_ipconfig_indicate_state(service,
1289                                         CONNMAN_SERVICE_STATE_DISCONNECT,
1290                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1291
1292         state = __connman_service_ipconfig_get_state(service,
1293                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1294         if (state != CONNMAN_SERVICE_STATE_IDLE &&
1295                                 state != CONNMAN_SERVICE_STATE_FAILURE)
1296                 __connman_service_ipconfig_indicate_state(service,
1297                                         CONNMAN_SERVICE_STATE_DISCONNECT,
1298                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1299
1300         __connman_service_ipconfig_indicate_state(service,
1301                                                 CONNMAN_SERVICE_STATE_IDLE,
1302                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1303
1304         __connman_service_ipconfig_indicate_state(service,
1305                                                 CONNMAN_SERVICE_STATE_IDLE,
1306                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1307 }
1308
1309 static gboolean __connman_network_clear_associating_delayed(gpointer user_data)
1310 {
1311         GSList *list;
1312         gboolean found = FALSE;
1313         enum connman_service_state state_ipv4;
1314         enum connman_service_state state_ipv6;
1315         struct connman_service *service;
1316         struct connman_network *network = (struct connman_network *)user_data;
1317
1318         for (list = network_list; list != NULL; list = list->next) {
1319                 struct connman_network *item = list->data;
1320
1321                 if (item == network) {
1322                         found = TRUE;
1323                         break;
1324                 }
1325         }
1326
1327         if (found != TRUE)
1328                 return FALSE;
1329
1330         DBG("network %p name %s", network, network->name);
1331         service = connman_service_lookup_from_network(network);
1332
1333         state_ipv4 = __connman_service_ipconfig_get_state(service,
1334                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1335         state_ipv6 = __connman_service_ipconfig_get_state(service,
1336                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1337
1338         DBG("service %p state %d/%d", service, state_ipv4, state_ipv6);
1339
1340         if (network->associating == FALSE &&
1341                         state_ipv4 == CONNMAN_SERVICE_STATE_ASSOCIATION &&
1342                         state_ipv6 == CONNMAN_SERVICE_STATE_ASSOCIATION) {
1343                 __connman_service_ipconfig_indicate_state(service,
1344                                 CONNMAN_SERVICE_STATE_IDLE,
1345                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1346                 __connman_service_ipconfig_indicate_state(service,
1347                                 CONNMAN_SERVICE_STATE_IDLE,
1348                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1349         } else {
1350                 if (network->associating == FALSE) {
1351                         struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
1352                         enum connman_ipconfig_method ipv4_method, ipv6_method;
1353
1354                         ipconfig_ipv4 = __connman_service_get_ip4config(service);
1355                         ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4);
1356                         ipconfig_ipv6 = __connman_service_get_ip4config(service);
1357                         ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6);
1358
1359                         if((ipv4_method == CONNMAN_IPCONFIG_METHOD_UNKNOWN || ipv4_method == CONNMAN_IPCONFIG_METHOD_OFF) &&
1360                                         (state_ipv6 == CONNMAN_SERVICE_STATE_ASSOCIATION))
1361                                 __connman_service_ipconfig_indicate_state(service,
1362                                                 CONNMAN_SERVICE_STATE_IDLE,
1363                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1364                         if((ipv6_method == CONNMAN_IPCONFIG_METHOD_UNKNOWN || ipv6_method == CONNMAN_IPCONFIG_METHOD_OFF) &&
1365                                         (state_ipv4 == CONNMAN_SERVICE_STATE_ASSOCIATION))
1366                                 __connman_service_ipconfig_indicate_state(service,
1367                                                 CONNMAN_SERVICE_STATE_IDLE,
1368                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1369                 }
1370         }
1371
1372         return FALSE;
1373 }
1374 #endif
1375
1376 /**
1377  * connman_network_set_associating:
1378  * @network: network structure
1379  * @associating: associating state
1380  *
1381  * Change associating state of network
1382  */
1383 int connman_network_set_associating(struct connman_network *network,
1384                                                 bool associating)
1385 {
1386         DBG("network %p associating %d", network, associating);
1387
1388         if (network->associating == associating)
1389                 return -EALREADY;
1390
1391         network->associating = associating;
1392
1393         if (associating) {
1394                 struct connman_service *service;
1395
1396                 service = connman_service_lookup_from_network(network);
1397                 __connman_service_ipconfig_indicate_state(service,
1398                                         CONNMAN_SERVICE_STATE_ASSOCIATION,
1399                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1400                 __connman_service_ipconfig_indicate_state(service,
1401                                         CONNMAN_SERVICE_STATE_ASSOCIATION,
1402                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1403         }
1404
1405 #if defined TIZEN_EXT
1406         if (associating == FALSE &&
1407                         connman_network_get_bool(network, "WiFi.UseWPS") == FALSE)
1408                 g_timeout_add_seconds(1,
1409                                 __connman_network_clear_associating_delayed,
1410                                 network);
1411 #endif
1412
1413         return 0;
1414 }
1415
1416 static void set_associate_error(struct connman_network *network)
1417 {
1418         struct connman_service *service;
1419
1420         service = connman_service_lookup_from_network(network);
1421
1422 #if defined TIZEN_EXT
1423         __connman_service_indicate_error(service,
1424                                         CONNMAN_SERVICE_ERROR_AUTH_FAILED);
1425 #else
1426         __connman_service_indicate_error(service,
1427                                         CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
1428 #endif
1429 }
1430
1431 static void set_configure_error(struct connman_network *network)
1432 {
1433         struct connman_service *service;
1434
1435         service = connman_service_lookup_from_network(network);
1436
1437         __connman_service_indicate_error(service,
1438                                         CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
1439 }
1440
1441 static void set_invalid_key_error(struct connman_network *network)
1442 {
1443         struct connman_service *service;
1444
1445         service = connman_service_lookup_from_network(network);
1446
1447 #if defined TIZEN_EXT
1448         if (service)
1449                 __connman_service_set_favorite(service, false);
1450 #endif
1451         __connman_service_indicate_error(service,
1452                                         CONNMAN_SERVICE_ERROR_INVALID_KEY);
1453 }
1454
1455 static void set_connect_error(struct connman_network *network)
1456 {
1457         struct connman_service *service;
1458
1459         service = connman_service_lookup_from_network(network);
1460
1461         __connman_service_indicate_error(service,
1462                                         CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
1463 }
1464
1465 static void set_blocked_error(struct connman_network *network)
1466 {
1467         struct connman_service *service;
1468
1469         service = connman_service_lookup_from_network(network);
1470
1471         __connman_service_indicate_error(service,
1472                                         CONNMAN_SERVICE_ERROR_BLOCKED);
1473 }
1474
1475
1476 #if defined TIZEN_EXT
1477 static void set_dhcp_error(struct connman_network *network)
1478 {
1479         struct connman_service *service;
1480
1481         if (network->associating != FALSE)
1482                 network->associating = FALSE;
1483
1484         service = connman_service_lookup_from_network(network);
1485
1486         __connman_service_indicate_error(service,
1487                                         CONNMAN_SERVICE_ERROR_DHCP_FAILED);
1488 }
1489 #endif
1490
1491 void connman_network_set_ipv4_method(struct connman_network *network,
1492                                         enum connman_ipconfig_method method)
1493 {
1494         struct connman_service *service;
1495         struct connman_ipconfig *ipconfig;
1496
1497         service = connman_service_lookup_from_network(network);
1498         if (!service)
1499                 return;
1500
1501         ipconfig = __connman_service_get_ip4config(service);
1502         if (!ipconfig)
1503                 return;
1504
1505         __connman_ipconfig_set_method(ipconfig, method);
1506 }
1507
1508 void connman_network_set_ipv6_method(struct connman_network *network,
1509                                         enum connman_ipconfig_method method)
1510 {
1511         struct connman_service *service;
1512         struct connman_ipconfig *ipconfig;
1513
1514         service = connman_service_lookup_from_network(network);
1515         if (!service)
1516                 return;
1517
1518         ipconfig = __connman_service_get_ip6config(service);
1519         if (!ipconfig)
1520                 return;
1521
1522         __connman_ipconfig_set_method(ipconfig, method);
1523 }
1524
1525 void connman_network_set_error(struct connman_network *network,
1526                                         enum connman_network_error error)
1527 {
1528         DBG("network %p error %d", network, error);
1529
1530         switch (error) {
1531         case CONNMAN_NETWORK_ERROR_UNKNOWN:
1532                 return;
1533         case CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL:
1534                 set_associate_error(network);
1535                 break;
1536         case CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL:
1537                 set_configure_error(network);
1538                 break;
1539         case CONNMAN_NETWORK_ERROR_INVALID_KEY:
1540                 set_invalid_key_error(network);
1541                 break;
1542         case CONNMAN_NETWORK_ERROR_CONNECT_FAIL:
1543                 set_connect_error(network);
1544                 break;
1545 #if defined TIZEN_EXT
1546         case CONNMAN_NETWORK_ERROR_DHCP_FAIL:
1547                 set_dhcp_error(network);
1548                 break;
1549 #endif
1550
1551         case CONNMAN_NETWORK_ERROR_BLOCKED:
1552                 set_blocked_error(network);
1553                 break;
1554
1555         }
1556
1557         __connman_network_disconnect(network);
1558 }
1559
1560 /**
1561  * connman_network_set_connected:
1562  * @network: network structure
1563  * @connected: connected state
1564  *
1565  * Change connected state of network
1566  */
1567 int connman_network_set_connected(struct connman_network *network,
1568                                                 bool connected)
1569 {
1570         DBG("network %p connected %d/%d connecting %d associating %d",
1571                 network, network->connected, connected, network->connecting,
1572                 network->associating);
1573
1574         if ((network->connecting || network->associating) &&
1575                                                         !connected) {
1576                 connman_network_set_error(network,
1577                                         CONNMAN_NETWORK_ERROR_CONNECT_FAIL);
1578                 return 0;
1579         }
1580
1581         if (network->connected == connected)
1582                 return -EALREADY;
1583
1584         if (!connected)
1585                 set_disconnected(network);
1586         else
1587                 set_connected(network);
1588
1589         return 0;
1590 }
1591
1592 /**
1593  * connman_network_get_connected:
1594  * @network: network structure
1595  *
1596  * Get network connection status
1597  */
1598 bool connman_network_get_connected(struct connman_network *network)
1599 {
1600         return network->connected;
1601 }
1602
1603 /**
1604  * connman_network_get_associating:
1605  * @network: network structure
1606  *
1607  * Get network associating status
1608  */
1609 bool connman_network_get_associating(struct connman_network *network)
1610 {
1611         return network->associating;
1612 }
1613
1614 void connman_network_clear_hidden(void *user_data)
1615 {
1616         if (!user_data)
1617                 return;
1618
1619         DBG("user_data %p", user_data);
1620
1621         /*
1622          * Hidden service does not have a connect timeout so
1623          * we do not need to remove it. We can just return
1624          * error to the caller telling that we could not find
1625          * any network that we could connect to.
1626          */
1627         connman_dbus_reply_pending(user_data, EIO, NULL);
1628 }
1629
1630 int connman_network_connect_hidden(struct connman_network *network,
1631                         char *identity, char *passphrase, void *user_data)
1632 {
1633         int err = 0;
1634         struct connman_service *service;
1635
1636         service = connman_service_lookup_from_network(network);
1637
1638         DBG("network %p service %p user_data %p", network, service, user_data);
1639
1640         if (!service)
1641                 return -EINVAL;
1642
1643         if (identity)
1644                 __connman_service_set_agent_identity(service, identity);
1645
1646         if (passphrase)
1647                 err = __connman_service_set_passphrase(service, passphrase);
1648
1649         if (err == -ENOKEY) {
1650                 __connman_service_indicate_error(service,
1651                                         CONNMAN_SERVICE_ERROR_INVALID_KEY);
1652                 goto out;
1653         } else {
1654                 __connman_service_set_hidden(service);
1655                 __connman_service_set_hidden_data(service, user_data);
1656                 return __connman_service_connect(service,
1657                                         CONNMAN_SERVICE_CONNECT_REASON_USER);
1658         }
1659
1660 out:
1661         __connman_service_return_error(service, -err, user_data);
1662         return err;
1663 }
1664
1665 /**
1666  * __connman_network_connect:
1667  * @network: network structure
1668  *
1669  * Connect network
1670  */
1671 int __connman_network_connect(struct connman_network *network)
1672 {
1673         int err;
1674
1675         DBG("network %p", network);
1676
1677         if (network->connected)
1678                 return -EISCONN;
1679
1680         if (network->connecting || network->associating)
1681                 return -EALREADY;
1682
1683         if (!network->driver)
1684                 return -EUNATCH;
1685
1686         if (!network->driver->connect)
1687                 return -ENOSYS;
1688
1689         if (!network->device)
1690                 return -ENODEV;
1691
1692         network->connecting = true;
1693
1694 #if defined TIZEN_EXT
1695         if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR)
1696 #endif
1697         __connman_device_disconnect(network->device);
1698 #if defined TIZEN_EXT
1699         DBG("ConnMan, Connect Request [%s]", network->name);
1700 #endif
1701         err = network->driver->connect(network);
1702         if (err < 0) {
1703                 if (err == -EINPROGRESS) {
1704 #if defined TIZEN_EXT
1705                         if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR)
1706 #endif
1707                         connman_network_set_associating(network, true);
1708                 } else
1709                         network->connecting = false;
1710
1711                 return err;
1712         }
1713
1714         set_connected(network);
1715
1716         return err;
1717 }
1718
1719 /**
1720  * __connman_network_disconnect:
1721  * @network: network structure
1722  *
1723  * Disconnect network
1724  */
1725 int __connman_network_disconnect(struct connman_network *network)
1726 {
1727         int err = 0;
1728
1729         DBG("network %p", network);
1730
1731         if (!network->connected && !network->connecting &&
1732                                                 !network->associating)
1733                 return -ENOTCONN;
1734
1735         if (!network->driver)
1736                 return -EUNATCH;
1737
1738         network->connecting = false;
1739 #if defined TIZEN_EXT
1740         DBG("ConnMan, Disconnect request");
1741 #endif
1742         if (network->driver->disconnect)
1743                 err = network->driver->disconnect(network);
1744
1745         if (err != -EINPROGRESS)
1746                 set_disconnected(network);
1747
1748         return err;
1749 }
1750
1751 int __connman_network_clear_ipconfig(struct connman_network *network,
1752                                         struct connman_ipconfig *ipconfig)
1753 {
1754         struct connman_service *service;
1755         struct connman_ipconfig *ipconfig_ipv4;
1756         enum connman_ipconfig_method method;
1757         enum connman_ipconfig_type type;
1758
1759         service = connman_service_lookup_from_network(network);
1760         if (!service)
1761                 return -EINVAL;
1762
1763         ipconfig_ipv4 = __connman_service_get_ip4config(service);
1764         method = __connman_ipconfig_get_method(ipconfig);
1765         type = __connman_ipconfig_get_config_type(ipconfig);
1766
1767         switch (method) {
1768         case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1769         case CONNMAN_IPCONFIG_METHOD_OFF:
1770         case CONNMAN_IPCONFIG_METHOD_FIXED:
1771                 return -EINVAL;
1772         case CONNMAN_IPCONFIG_METHOD_AUTO:
1773                 release_dhcpv6(network);
1774                 break;
1775         case CONNMAN_IPCONFIG_METHOD_MANUAL:
1776                 __connman_ipconfig_address_remove(ipconfig);
1777                 break;
1778         case CONNMAN_IPCONFIG_METHOD_DHCP:
1779                 __connman_dhcp_stop(ipconfig_ipv4);
1780                 break;
1781         }
1782
1783         if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1784                 __connman_service_ipconfig_indicate_state(service,
1785                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
1786                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1787         else if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1788                 __connman_service_ipconfig_indicate_state(service,
1789                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
1790                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1791
1792         return 0;
1793 }
1794
1795 #if defined TIZEN_EXT
1796 void __connman_network_set_auto_ipv6_gateway(char *gateway, void *user_data)
1797 {
1798         DBG("");
1799
1800         struct connman_network *network = user_data;
1801         struct connman_service *service;
1802         struct connman_ipconfig *ipconfig = NULL;
1803
1804         service = connman_service_lookup_from_network(network);
1805         if (service == NULL)
1806                 return;
1807
1808         ipconfig = __connman_service_get_ipconfig(service, AF_INET6);
1809         if (ipconfig == NULL)
1810                 return;
1811
1812         __connman_ipconfig_set_gateway(ipconfig, gateway);
1813
1814         return;
1815 }
1816 #endif
1817
1818 int __connman_network_enable_ipconfig(struct connman_network *network,
1819                                 struct connman_ipconfig *ipconfig)
1820 {
1821         int r = 0;
1822         enum connman_ipconfig_type type;
1823         enum connman_ipconfig_method method;
1824 #if defined TIZEN_EXT
1825         struct connman_service *service;
1826 #endif
1827
1828         if (!network || !ipconfig)
1829                 return -EINVAL;
1830
1831         type = __connman_ipconfig_get_config_type(ipconfig);
1832
1833         switch (type) {
1834         case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
1835         case CONNMAN_IPCONFIG_TYPE_ALL:
1836                 return -ENOSYS;
1837
1838         case CONNMAN_IPCONFIG_TYPE_IPV6:
1839 #if !defined TIZEN_EXT
1840                 set_configuration(network, type);
1841 #endif
1842
1843                 method = __connman_ipconfig_get_method(ipconfig);
1844
1845                 DBG("ipv6 ipconfig method %d", method);
1846
1847                 switch (method) {
1848                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1849                         break;
1850
1851                 case CONNMAN_IPCONFIG_METHOD_OFF:
1852                         __connman_ipconfig_disable_ipv6(ipconfig);
1853                         break;
1854
1855                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1856 #if defined TIZEN_EXT
1857                 service = connman_service_lookup_from_network(network);
1858
1859                 if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR)
1860                         __connman_service_ipconfig_indicate_state(service,
1861                                 CONNMAN_SERVICE_STATE_CONFIGURATION,
1862                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1863 #endif
1864 #if !defined TIZEN_EXT
1865                         autoconf_ipv6_set(network);
1866 #endif
1867                         break;
1868
1869                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1870                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1871 #if defined TIZEN_EXT
1872                         set_configuration(network, type);
1873 #endif
1874                         r = manual_ipv6_set(network, ipconfig);
1875                         break;
1876
1877                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1878                         r = -ENOSYS;
1879                         break;
1880                 }
1881
1882                 break;
1883
1884         case CONNMAN_IPCONFIG_TYPE_IPV4:
1885                 set_configuration(network, type);
1886
1887                 method = __connman_ipconfig_get_method(ipconfig);
1888
1889                 DBG("ipv4 ipconfig method %d", method);
1890
1891                 switch (method) {
1892                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1893                 case CONNMAN_IPCONFIG_METHOD_OFF:
1894                         break;
1895
1896                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1897                         r = -ENOSYS;
1898                         break;
1899
1900                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1901                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1902                         r = set_connected_manual(network);
1903                         break;
1904
1905                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1906                         r = set_connected_dhcp(network);
1907                         break;
1908                 }
1909
1910                 break;
1911         }
1912
1913         if (r < 0)
1914                 connman_network_set_error(network,
1915                                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
1916
1917         return r;
1918 }
1919
1920 int connman_network_set_ipaddress(struct connman_network *network,
1921                                         struct connman_ipaddress *ipaddress)
1922 {
1923         struct connman_service *service;
1924         struct connman_ipconfig *ipconfig = NULL;
1925
1926         DBG("network %p", network);
1927
1928         service = connman_service_lookup_from_network(network);
1929         if (!service)
1930                 return -EINVAL;
1931
1932         ipconfig = __connman_service_get_ipconfig(service, ipaddress->family);
1933         if (!ipconfig)
1934                 return -EINVAL;
1935
1936         __connman_ipconfig_set_local(ipconfig, ipaddress->local);
1937         __connman_ipconfig_set_peer(ipconfig, ipaddress->peer);
1938         __connman_ipconfig_set_broadcast(ipconfig, ipaddress->broadcast);
1939         __connman_ipconfig_set_prefixlen(ipconfig, ipaddress->prefixlen);
1940         __connman_ipconfig_set_gateway(ipconfig, ipaddress->gateway);
1941
1942         return 0;
1943 }
1944
1945 #if defined TIZEN_EXT
1946 /*
1947  * Description: Network client requires additional wifi specific info
1948  */
1949 int connman_network_set_bssid(struct connman_network *network,
1950                                 const unsigned char *bssid)
1951 {
1952         int i = 0;
1953
1954         if (bssid == NULL)
1955                 return -EINVAL;
1956
1957         DBG("network %p bssid %02x:%02x:%02x:%02x:%02x:%02x", network,
1958                         bssid[0], bssid[1], bssid[2],
1959                         bssid[3], bssid[4], bssid[5]);
1960
1961         for (;i < WIFI_BSSID_LEN_MAX;i++)
1962                 network->wifi.bssid[i] = bssid[i];
1963
1964         return 0;
1965 }
1966
1967 unsigned char *connman_network_get_bssid(struct connman_network *network)
1968 {
1969         return (unsigned char *)network->wifi.bssid;
1970 }
1971
1972 int connman_network_set_maxrate(struct connman_network *network,
1973                                 unsigned int maxrate)
1974 {
1975 #if !defined TIZEN_EXT
1976         DBG("network %p maxrate %d", network, maxrate);
1977 #endif
1978
1979         network->wifi.maxrate = maxrate;
1980
1981         return 0;
1982 }
1983
1984 unsigned int connman_network_get_maxrate(struct connman_network *network)
1985 {
1986         return network->wifi.maxrate;
1987 }
1988
1989 int connman_network_set_enc_mode(struct connman_network *network,
1990                                 const char *encryption_mode)
1991 {
1992         if (encryption_mode == NULL)
1993                 return -EINVAL;
1994
1995         DBG("network %p encryption mode %s", network, encryption_mode);
1996
1997         g_strlcpy(network->wifi.encryption_mode, encryption_mode,
1998                                         WIFI_ENCYPTION_MODE_LEN_MAX);
1999
2000         return 0;
2001 }
2002
2003 const char *connman_network_get_enc_mode(struct connman_network *network)
2004 {
2005         return (const char *)network->wifi.encryption_mode;
2006 }
2007
2008 int connman_network_set_rsn_mode(struct connman_network *network,
2009                                 bool rsn_mode)
2010 {
2011         network->wifi.rsn_mode = rsn_mode;
2012
2013         return 0;
2014 }
2015
2016 int connman_network_set_proxy(struct connman_network *network,
2017                                 const char *proxies)
2018 {
2019         struct connman_service *service;
2020
2021         DBG("network %p proxies %s", network, proxies);
2022
2023         service = connman_service_lookup_from_network(network);
2024         if (service == NULL)
2025                 return -EINVAL;
2026
2027         __connman_service_set_proxy(service, proxies);
2028
2029         connman_service_set_proxy_method(service,
2030                                 CONNMAN_SERVICE_PROXY_METHOD_MANUAL);
2031
2032         return 0;
2033 }
2034
2035 int connman_network_set_is_hs20AP(struct connman_network *network,
2036                                 unsigned int isHS20AP)
2037 {
2038         if (!network)
2039                 return 0;
2040
2041         network->wifi.isHS20AP = isHS20AP;
2042
2043         return 0;
2044 }
2045
2046 unsigned int connman_network_get_is_hs20AP(struct connman_network *network)
2047 {
2048         if (!network)
2049                 return 0;
2050
2051         return network->wifi.isHS20AP;
2052 }
2053
2054 int connman_network_set_keymgmt(struct connman_network *network,
2055                                 unsigned int keymgmt)
2056 {
2057         if (network == NULL)
2058                 return 0;
2059
2060         network->wifi.keymgmt = keymgmt;
2061
2062         return 0;
2063 }
2064
2065 unsigned int connman_network_get_keymgmt(struct connman_network *network)
2066 {
2067         if (network == NULL)
2068                 return 0;
2069
2070         return network->wifi.keymgmt;
2071 }
2072
2073 int connman_network_set_disconnect_reason(struct connman_network *network,
2074                                 int reason_code)
2075 {
2076         if (network == NULL)
2077                 return 0;
2078
2079         network->wifi.disconnect_reason = reason_code;
2080
2081         return 0;
2082 }
2083
2084 int connman_network_get_disconnect_reason(struct connman_network *network)
2085 {
2086         if (network == NULL)
2087                 return 0;
2088
2089         return network->wifi.disconnect_reason;
2090 }
2091 #endif
2092
2093 int connman_network_set_nameservers(struct connman_network *network,
2094                                 const char *nameservers)
2095 {
2096         struct connman_service *service;
2097         char **nameservers_array;
2098         int i;
2099
2100         DBG("network %p nameservers %s", network, nameservers);
2101
2102         service = connman_service_lookup_from_network(network);
2103         if (!service)
2104                 return -EINVAL;
2105
2106         __connman_service_nameserver_clear(service);
2107
2108         if (!nameservers)
2109                 return 0;
2110
2111         nameservers_array = g_strsplit(nameservers, " ", 0);
2112
2113         for (i = 0; nameservers_array[i]; i++) {
2114 #if defined TIZEN_EXT
2115                 __connman_service_nameserver_append(service,
2116                                                 nameservers_array[i], false,
2117                                                 CONNMAN_IPCONFIG_TYPE_ALL);
2118 #else
2119                 __connman_service_nameserver_append(service,
2120                                                 nameservers_array[i], false);
2121 #endif
2122         }
2123
2124         g_strfreev(nameservers_array);
2125
2126         return 0;
2127 }
2128
2129 int connman_network_set_domain(struct connman_network *network,
2130                                 const char *domain)
2131 {
2132         struct connman_service *service;
2133
2134         DBG("network %p domain %s", network, domain);
2135
2136         service = connman_service_lookup_from_network(network);
2137         if (!service)
2138                 return -EINVAL;
2139
2140         __connman_service_set_domainname(service, domain);
2141
2142         return 0;
2143 }
2144
2145 /**
2146  * connman_network_set_name:
2147  * @network: network structure
2148  * @name: name value
2149  *
2150  * Set display name value for network
2151  */
2152 int connman_network_set_name(struct connman_network *network,
2153                                                         const char *name)
2154 {
2155         DBG("network %p name %s", network, name);
2156
2157         g_free(network->name);
2158         network->name = g_strdup(name);
2159
2160         return 0;
2161 }
2162
2163 /**
2164  * connman_network_set_strength:
2165  * @network: network structure
2166  * @strength: strength value
2167  *
2168  * Set signal strength value for network
2169  */
2170
2171 int connman_network_set_strength(struct connman_network *network,
2172                                                 uint8_t strength)
2173 {
2174 #if !defined TIZEN_EXT
2175         DBG("network %p strengh %d", network, strength);
2176 #endif
2177
2178         network->strength = strength;
2179
2180         return 0;
2181 }
2182
2183 uint8_t connman_network_get_strength(struct connman_network *network)
2184 {
2185         return network->strength;
2186 }
2187
2188 int connman_network_set_frequency(struct connman_network *network,
2189                                                 uint16_t frequency)
2190 {
2191 #if !defined TIZEN_EXT
2192         DBG("network %p frequency %d", network, frequency);
2193 #endif
2194
2195         network->frequency = frequency;
2196
2197         return 0;
2198 }
2199
2200 uint16_t connman_network_get_frequency(struct connman_network *network)
2201 {
2202         return network->frequency;
2203 }
2204
2205 int connman_network_set_wifi_channel(struct connman_network *network,
2206                                                 uint16_t channel)
2207 {
2208         DBG("network %p wifi channel %d", network, channel);
2209
2210         network->wifi.channel = channel;
2211
2212         return 0;
2213 }
2214
2215 uint16_t connman_network_get_wifi_channel(struct connman_network *network)
2216 {
2217         return network->wifi.channel;
2218 }
2219
2220 /**
2221  * connman_network_set_string:
2222  * @network: network structure
2223  * @key: unique identifier
2224  * @value: string value
2225  *
2226  * Set string value for specific key
2227  */
2228 int connman_network_set_string(struct connman_network *network,
2229                                         const char *key, const char *value)
2230 {
2231 #if !defined TIZEN_EXT
2232         DBG("network %p key %s value %s", network, key, value);
2233 #endif
2234
2235         if (g_strcmp0(key, "Name") == 0)
2236                 return connman_network_set_name(network, value);
2237
2238         if (g_str_equal(key, "Path")) {
2239                 g_free(network->path);
2240                 network->path = g_strdup(value);
2241         } else if (g_str_equal(key, "Node")) {
2242                 g_free(network->node);
2243                 network->node = g_strdup(value);
2244         } else if (g_str_equal(key, "WiFi.Mode")) {
2245                 g_free(network->wifi.mode);
2246                 network->wifi.mode = g_strdup(value);
2247         } else if (g_str_equal(key, "WiFi.Security")) {
2248                 g_free(network->wifi.security);
2249                 network->wifi.security = g_strdup(value);
2250         } else if (g_str_equal(key, "WiFi.Passphrase")) {
2251 #if defined TIZEN_EXT
2252                 DBG("ConnMan, %p key %s", network, key);
2253 #endif
2254                 g_free(network->wifi.passphrase);
2255                 network->wifi.passphrase = g_strdup(value);
2256         } else if (g_str_equal(key, "WiFi.EAP")) {
2257                 g_free(network->wifi.eap);
2258                 network->wifi.eap = g_strdup(value);
2259         } else if (g_str_equal(key, "WiFi.Identity")) {
2260                 g_free(network->wifi.identity);
2261                 network->wifi.identity = g_strdup(value);
2262         } else if (g_str_equal(key, "WiFi.AgentIdentity")) {
2263                 g_free(network->wifi.agent_identity);
2264                 network->wifi.agent_identity = g_strdup(value);
2265         } else if (g_str_equal(key, "WiFi.CACertFile")) {
2266                 g_free(network->wifi.ca_cert_path);
2267                 network->wifi.ca_cert_path = g_strdup(value);
2268         } else if (g_str_equal(key, "WiFi.ClientCertFile")) {
2269                 g_free(network->wifi.client_cert_path);
2270                 network->wifi.client_cert_path = g_strdup(value);
2271         } else if (g_str_equal(key, "WiFi.PrivateKeyFile")) {
2272                 g_free(network->wifi.private_key_path);
2273                 network->wifi.private_key_path = g_strdup(value);
2274         } else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase")) {
2275                 g_free(network->wifi.private_key_passphrase);
2276                 network->wifi.private_key_passphrase = g_strdup(value);
2277         } else if (g_str_equal(key, "WiFi.Phase2")) {
2278                 g_free(network->wifi.phase2_auth);
2279                 network->wifi.phase2_auth = g_strdup(value);
2280         } else if (g_str_equal(key, "WiFi.PinWPS")) {
2281                 g_free(network->wifi.pin_wps);
2282                 network->wifi.pin_wps = g_strdup(value);
2283         } else {
2284                 return -EINVAL;
2285         }
2286
2287         return 0;
2288 }
2289
2290 /**
2291  * connman_network_get_string:
2292  * @network: network structure
2293  * @key: unique identifier
2294  *
2295  * Get string value for specific key
2296  */
2297 const char *connman_network_get_string(struct connman_network *network,
2298                                                         const char *key)
2299 {
2300 #if !defined TIZEN_EXT
2301         DBG("network %p key %s", network, key);
2302 #endif
2303
2304         if (g_str_equal(key, "Path"))
2305                 return network->path;
2306         else if (g_str_equal(key, "Name"))
2307                 return network->name;
2308         else if (g_str_equal(key, "Node"))
2309                 return network->node;
2310         else if (g_str_equal(key, "WiFi.Mode"))
2311                 return network->wifi.mode;
2312         else if (g_str_equal(key, "WiFi.Security"))
2313 #if defined TIZEN_EXT
2314                 if (network->wifi.rsn_mode != true ||
2315                     g_str_equal(network->wifi.security, "ieee8021x"))
2316                         return network->wifi.security;
2317                 else
2318                         return "rsn";
2319 #else
2320                 return network->wifi.security;
2321 #endif
2322         else if (g_str_equal(key, "WiFi.Passphrase"))
2323                 return network->wifi.passphrase;
2324         else if (g_str_equal(key, "WiFi.EAP"))
2325                 return network->wifi.eap;
2326         else if (g_str_equal(key, "WiFi.Identity"))
2327                 return network->wifi.identity;
2328         else if (g_str_equal(key, "WiFi.AgentIdentity"))
2329                 return network->wifi.agent_identity;
2330         else if (g_str_equal(key, "WiFi.CACertFile"))
2331                 return network->wifi.ca_cert_path;
2332         else if (g_str_equal(key, "WiFi.ClientCertFile"))
2333                 return network->wifi.client_cert_path;
2334         else if (g_str_equal(key, "WiFi.PrivateKeyFile"))
2335                 return network->wifi.private_key_path;
2336         else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase"))
2337                 return network->wifi.private_key_passphrase;
2338         else if (g_str_equal(key, "WiFi.Phase2"))
2339                 return network->wifi.phase2_auth;
2340         else if (g_str_equal(key, "WiFi.PinWPS"))
2341                 return network->wifi.pin_wps;
2342
2343         return NULL;
2344 }
2345
2346 /**
2347  * connman_network_set_bool:
2348  * @network: network structure
2349  * @key: unique identifier
2350  * @value: boolean value
2351  *
2352  * Set boolean value for specific key
2353  */
2354 int connman_network_set_bool(struct connman_network *network,
2355                                         const char *key, bool value)
2356 {
2357 #if !defined TIZEN_EXT
2358         DBG("network %p key %s value %d", network, key, value);
2359 #endif
2360
2361         if (g_strcmp0(key, "Roaming") == 0)
2362                 network->roaming = value;
2363         else if (g_strcmp0(key, "WiFi.WPS") == 0)
2364                 network->wifi.wps = value;
2365         else if (g_strcmp0(key, "WiFi.UseWPS") == 0)
2366                 network->wifi.use_wps = value;
2367 #if defined TIZEN_EXT
2368         else if (g_strcmp0(key, "DefaultInternet") == 0)
2369                 network->default_internet = value;
2370 #endif
2371
2372         return -EINVAL;
2373 }
2374
2375 /**
2376  * connman_network_get_bool:
2377  * @network: network structure
2378  * @key: unique identifier
2379  *
2380  * Get boolean value for specific key
2381  */
2382 bool connman_network_get_bool(struct connman_network *network,
2383                                                         const char *key)
2384 {
2385 #if !defined TIZEN_EXT
2386         DBG("network %p key %s", network, key);
2387 #endif
2388
2389         if (g_str_equal(key, "Roaming"))
2390                 return network->roaming;
2391         else if (g_str_equal(key, "WiFi.WPS"))
2392                 return network->wifi.wps;
2393         else if (g_str_equal(key, "WiFi.UseWPS"))
2394                 return network->wifi.use_wps;
2395 #if defined TIZEN_EXT
2396         else if (g_str_equal(key, "DefaultInternet"))
2397                 return network->default_internet;
2398 #endif
2399
2400         return false;
2401 }
2402
2403 /**
2404  * connman_network_set_blob:
2405  * @network: network structure
2406  * @key: unique identifier
2407  * @data: blob data
2408  * @size: blob size
2409  *
2410  * Set binary blob value for specific key
2411  */
2412 int connman_network_set_blob(struct connman_network *network,
2413                         const char *key, const void *data, unsigned int size)
2414 {
2415 #if !defined TIZEN_EXT
2416         DBG("network %p key %s size %d", network, key, size);
2417 #endif
2418
2419         if (g_str_equal(key, "WiFi.SSID")) {
2420                 g_free(network->wifi.ssid);
2421                 network->wifi.ssid = g_try_malloc(size);
2422                 if (network->wifi.ssid) {
2423                         memcpy(network->wifi.ssid, data, size);
2424                         network->wifi.ssid_len = size;
2425                 } else
2426                         network->wifi.ssid_len = 0;
2427         } else {
2428                 return -EINVAL;
2429         }
2430
2431         return 0;
2432 }
2433
2434 /**
2435  * connman_network_get_blob:
2436  * @network: network structure
2437  * @key: unique identifier
2438  * @size: pointer to blob size
2439  *
2440  * Get binary blob value for specific key
2441  */
2442 const void *connman_network_get_blob(struct connman_network *network,
2443                                         const char *key, unsigned int *size)
2444 {
2445         DBG("network %p key %s", network, key);
2446
2447         if (g_str_equal(key, "WiFi.SSID")) {
2448                 if (size)
2449                         *size = network->wifi.ssid_len;
2450                 return network->wifi.ssid;
2451         }
2452
2453         return NULL;
2454 }
2455
2456 void __connman_network_set_device(struct connman_network *network,
2457                                         struct connman_device *device)
2458 {
2459         if (network->device == device)
2460                 return;
2461
2462         if (network->device)
2463                 network_remove(network);
2464
2465         network->device = device;
2466
2467         if (network->device)
2468                 network_probe(network);
2469 }
2470
2471 /**
2472  * connman_network_get_device:
2473  * @network: network structure
2474  *
2475  * Get parent device of network
2476  */
2477 struct connman_device *connman_network_get_device(struct connman_network *network)
2478 {
2479         return network->device;
2480 }
2481
2482 /**
2483  * connman_network_get_data:
2484  * @network: network structure
2485  *
2486  * Get private network data pointer
2487  */
2488 void *connman_network_get_data(struct connman_network *network)
2489 {
2490         return network->driver_data;
2491 }
2492
2493 /**
2494  * connman_network_set_data:
2495  * @network: network structure
2496  * @data: data pointer
2497  *
2498  * Set private network data pointer
2499  */
2500 void connman_network_set_data(struct connman_network *network, void *data)
2501 {
2502         network->driver_data = data;
2503 }
2504
2505 void connman_network_update(struct connman_network *network)
2506 {
2507         switch (network->type) {
2508         case CONNMAN_NETWORK_TYPE_UNKNOWN:
2509         case CONNMAN_NETWORK_TYPE_VENDOR:
2510                 return;
2511         case CONNMAN_NETWORK_TYPE_ETHERNET:
2512         case CONNMAN_NETWORK_TYPE_GADGET:
2513         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
2514         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
2515         case CONNMAN_NETWORK_TYPE_CELLULAR:
2516         case CONNMAN_NETWORK_TYPE_WIFI:
2517                 break;
2518         }
2519
2520         if (network->group)
2521                 __connman_service_update_from_network(network);
2522 }
2523
2524 int __connman_network_init(void)
2525 {
2526         DBG("");
2527
2528         return 0;
2529 }
2530
2531 void __connman_network_cleanup(void)
2532 {
2533         DBG("");
2534 }