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