Support PSK_SHA256 for ieee80211w
[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 #include <connman/acd.h>
31 #include "src/shared/arp.h"
32
33 #if defined TIZEN_EXT
34 #include <gdbus.h>
35
36 static DBusConnection *connection;
37 #endif
38
39 /*
40  * How many times to send RS with the purpose of
41  * refreshing RDNSS entries before they actually expire.
42  * With a value of 1, one RS will be sent, with no retries.
43  */
44 #define RS_REFRESH_COUNT        1
45
46 /*
47  * Value in seconds to wait for RA after RS was sent.
48  * After this time elapsed, we can send another RS.
49  */
50 #define RS_REFRESH_TIMEOUT      3
51
52 /*
53  * As per RFC 4861, a host should transmit up to MAX_RTR_SOLICITATIONS(3)
54  * Router Solicitation messages, each separated by at least
55  * RTR_SOLICITATION_INTERVAL(4) seconds to obtain RA for IPv6 auto-configuration.
56  */
57 #define RTR_SOLICITATION_INTERVAL       4
58
59 #define DHCP_RETRY_TIMEOUT     10
60
61 #if defined TIZEN_EXT
62 static unsigned char invalid_bssid[WIFI_BSSID_LEN_MAX] = {
63         0x00, 0x00, 0x00, 0x00, 0x00, 0x00
64 };
65 #endif
66
67 static GSList *network_list = NULL;
68 static GSList *driver_list = NULL;
69
70 struct connman_network {
71         int refcount;
72         enum connman_network_type type;
73         bool available;
74         bool connected;
75         bool roaming;
76         uint8_t strength;
77         uint16_t frequency;
78         char *identifier;
79         char *name;
80         char *node;
81         char *group;
82         char *path;
83         int index;
84         int router_solicit_count;
85         int router_solicit_refresh_count;
86         struct acd_host *acd_host;
87         guint ipv4ll_timeout;
88         guint dhcp_timeout;
89
90         struct connman_network_driver *driver;
91         void *driver_data;
92
93         bool connecting;
94         bool associating;
95
96         struct connman_device *device;
97
98         struct {
99                 void *ssid;
100                 int ssid_len;
101                 char *mode;
102                 unsigned short channel;
103                 char *security;
104                 char *passphrase;
105                 char *eap;
106                 char *identity;
107                 char *anonymous_identity;
108                 char *agent_identity;
109                 char *ca_cert_path;
110                 char *subject_match;
111                 char *altsubject_match;
112                 char *domain_suffix_match;
113                 char *domain_match;
114                 char *client_cert_path;
115                 char *private_key_path;
116                 char *private_key_passphrase;
117                 char *phase2_auth;
118                 bool wps;
119                 bool wps_advertizing;
120                 bool use_wps;
121                 char *pin_wps;
122 #if defined TIZEN_EXT
123                 char encryption_mode[WIFI_ENCYPTION_MODE_LEN_MAX];
124                 unsigned char bssid[WIFI_BSSID_LEN_MAX];
125                 unsigned int maxrate;
126                 int maxspeed;
127                 bool isHS20AP;
128                 unsigned int keymgmt;
129                 char *keymgmt_type;
130                 bool rsn_mode;
131                 bool pmf_required;
132                 int disconnect_reason;
133                 int assoc_status_code;
134                 GSList *vsie_list;
135                 /*
136                 * Only for EAP-FAST
137                 */
138                 char *phase1;
139                 unsigned char country_code[WIFI_COUNTRY_CODE_LEN];
140                 GSList *bssid_list;
141                 GSList *sec_list;
142                 ieee80211_modes_e phy_mode;
143                 connection_mode_e connection_mode;
144                 char *connector;
145                 char *c_sign_key;
146                 char *net_access_key;
147 #endif
148 #if defined TIZEN_EXT
149                 unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX];
150                 GHashTable *assoc_reject_table;
151                 bool owe_transition_mode;
152                 void *transition_mode_ssid;
153                 int transition_mode_ssid_len;
154                 unsigned char transition_mode_bssid[WIFI_BSSID_LEN_MAX];
155                 bool roaming_progress;
156                 bool roaming_dhcp;
157                 char *roaming_cur_bssid;
158                 char *roaming_dst_bssid;
159                 __time_t roam_scan_time;
160                 unsigned int max_bssid_count;
161                 int snr;
162 #endif
163         } wifi;
164
165 #if defined TIZEN_EXT
166         /* Multiple APN services and a default APN which a user selected */
167         bool default_internet;
168         bool is_psk_sha256;
169 #endif
170
171 };
172
173 static const char *type2string(enum connman_network_type type)
174 {
175         switch (type) {
176         case CONNMAN_NETWORK_TYPE_UNKNOWN:
177         case CONNMAN_NETWORK_TYPE_VENDOR:
178                 break;
179         case CONNMAN_NETWORK_TYPE_ETHERNET:
180                 return "ethernet";
181         case CONNMAN_NETWORK_TYPE_GADGET:
182                 return "gadget";
183         case CONNMAN_NETWORK_TYPE_WIFI:
184                 return "wifi";
185         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
186         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
187                 return "bluetooth";
188         case CONNMAN_NETWORK_TYPE_CELLULAR:
189                 return "cellular";
190         }
191
192         return NULL;
193 }
194
195 static bool match_driver(struct connman_network *network,
196                                         struct connman_network_driver *driver)
197 {
198         if (network->type == driver->type ||
199                         driver->type == CONNMAN_NETWORK_TYPE_UNKNOWN)
200                 return true;
201
202         return false;
203 }
204
205 static void set_configuration(struct connman_network *network,
206                         enum connman_ipconfig_type type)
207 {
208         struct connman_service *service;
209
210         DBG("network %p", network);
211
212         if (!network->device)
213                 return;
214
215         __connman_device_set_network(network->device, network);
216
217         service = connman_service_lookup_from_network(network);
218         __connman_service_ipconfig_indicate_state(service,
219                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
220                                         type);
221 }
222
223 void connman_network_append_acddbus(DBusMessageIter *dict,
224                 struct connman_network *network)
225 {
226         if (!network->acd_host)
227                 return;
228
229         acd_host_append_dbus_property(network->acd_host, dict);
230 }
231
232 static int start_acd(struct connman_network *network);
233
234 static void remove_ipv4ll_timeout(struct connman_network *network)
235 {
236         if (network->ipv4ll_timeout > 0) {
237                 g_source_remove(network->ipv4ll_timeout);
238                 network->ipv4ll_timeout = 0;
239         }
240 }
241
242 static void acd_host_ipv4_available(struct acd_host *acd, gpointer user_data)
243 {
244         struct connman_network *network = user_data;
245         struct connman_service *service;
246         struct connman_ipconfig *ipconfig_ipv4;
247         int err;
248
249         if (!network)
250                 return;
251
252         service = connman_service_lookup_from_network(network);
253         if (!service)
254                 return;
255
256         ipconfig_ipv4 = __connman_service_get_ip4config(service);
257         if (!ipconfig_ipv4) {
258                 connman_error("Service has no IPv4 configuration");
259                 return;
260         }
261
262         err = __connman_ipconfig_address_add(ipconfig_ipv4);
263         if (err < 0)
264                 goto err;
265
266 #if defined TIZEN_EXT
267         err = __connman_ipconfig_gateway_add(ipconfig_ipv4, service);
268 #else
269         err = __connman_ipconfig_gateway_add(ipconfig_ipv4);
270 #endif
271         if (err < 0)
272                 goto err;
273
274         __connman_service_save(service);
275
276         return;
277
278 err:
279         connman_network_set_error(__connman_service_get_network(service),
280                                 CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
281 }
282
283 static int start_ipv4ll(struct connman_network *network)
284 {
285         struct connman_service *service;
286         struct connman_ipconfig *ipconfig_ipv4;
287         struct in_addr addr;
288         char *address;
289
290         service = connman_service_lookup_from_network(network);
291         if (!service)
292                 return -EINVAL;
293
294         ipconfig_ipv4 = __connman_service_get_ip4config(service);
295         if (!ipconfig_ipv4) {
296                 connman_error("Service has no IPv4 configuration");
297                 return -EINVAL;
298         }
299
300         /* Apply random IPv4 address. */
301         addr.s_addr = htonl(arp_random_ip());
302         address = inet_ntoa(addr);
303         if (!address) {
304                 connman_error("Could not convert IPv4LL random address %u",
305                                 addr.s_addr);
306                 return -EINVAL;
307         }
308         __connman_ipconfig_set_local(ipconfig_ipv4, address);
309
310         connman_info("Probing IPv4LL address %s", address);
311         return start_acd(network);
312 }
313
314 static gboolean start_ipv4ll_ontimeout(gpointer data)
315 {
316         struct connman_network *network = data;
317
318         if (!network)
319                 return FALSE;
320
321         /* Start IPv4LL ACD. */
322         start_ipv4ll(network);
323
324         return FALSE;
325 }
326
327 static void acd_host_ipv4_lost(struct acd_host *acd, gpointer user_data)
328 {
329         struct connman_network *network = user_data;
330         struct connman_service *service;
331         struct connman_ipconfig *ipconfig_ipv4;
332         enum connman_ipconfig_type type;
333         enum connman_ipconfig_method method;
334
335         if (!network)
336                 return;
337
338         service = connman_service_lookup_from_network(network);
339         if (!service)
340                 return;
341
342         ipconfig_ipv4 = __connman_service_get_ip4config(service);
343         if (!ipconfig_ipv4) {
344                 connman_error("Service has no IPv4 configuration");
345                 return;
346         }
347
348         type = __connman_ipconfig_get_config_type(ipconfig_ipv4);
349         if (type != CONNMAN_IPCONFIG_TYPE_IPV4)
350                 return;
351
352         __connman_ipconfig_address_remove(ipconfig_ipv4);
353
354         method = __connman_ipconfig_get_method(ipconfig_ipv4);
355         if (method == CONNMAN_IPCONFIG_METHOD_DHCP) {
356                 /*
357                  * We have one more chance for DHCP. If this fails
358                  * acd_host_ipv4_conflict will be called.
359                  */
360                 network = __connman_service_get_network(service);
361                 if (network)
362                         __connman_network_enable_ipconfig(network, ipconfig_ipv4);
363         } else {
364                 /* Start IPv4LL ACD. */
365                 start_ipv4ll(network);
366         }
367 }
368
369 static void acd_host_ipv4_conflict(struct acd_host *acd, gpointer user_data)
370 {
371         struct connman_network *network = user_data;
372         struct connman_service *service;
373         struct connman_ipconfig *ipconfig_ipv4;
374         enum connman_ipconfig_method method;
375
376         service = connman_service_lookup_from_network(network);
377         if (!service)
378                 return;
379
380         ipconfig_ipv4 = __connman_service_get_ip4config(service);
381         if (!ipconfig_ipv4) {
382                 connman_error("Service has no IPv4 configuration");
383                 return;
384         }
385
386         method = __connman_ipconfig_get_method(ipconfig_ipv4);
387         connman_info("%s conflict counts=%u", __FUNCTION__,
388                         acd_host_get_conflicts_count(acd));
389
390         if (method == CONNMAN_IPCONFIG_METHOD_DHCP &&
391                         acd_host_get_conflicts_count(acd) < 2) {
392                 connman_info("%s Sending DHCP decline", __FUNCTION__);
393                 __connman_dhcp_decline(ipconfig_ipv4);
394
395                 connman_network_set_connected_dhcp_later(network, DHCP_RETRY_TIMEOUT);
396                 __connman_ipconfig_set_local(ipconfig_ipv4, NULL);
397         } else {
398                 if (method == CONNMAN_IPCONFIG_METHOD_DHCP) {
399                         __connman_ipconfig_set_method(ipconfig_ipv4,
400                                         CONNMAN_IPCONFIG_METHOD_AUTO);
401                         __connman_dhcp_decline(ipconfig_ipv4);
402                 }
403                 /* Start IPv4LL ACD. */
404                 start_ipv4ll(network);
405         }
406 }
407
408 static void acd_host_ipv4_maxconflict(struct acd_host *acd, gpointer user_data)
409 {
410         struct connman_network *network = user_data;
411
412         remove_ipv4ll_timeout(network);
413         connman_info("Had maximum number of conflicts. Next IPv4LL address will be "
414                         "tried in %d seconds", RATE_LIMIT_INTERVAL);
415         /* Wait, then start IPv4LL ACD. */
416         network->ipv4ll_timeout =
417                 g_timeout_add_seconds_full(G_PRIORITY_HIGH,
418                                 RATE_LIMIT_INTERVAL,
419                                 start_ipv4ll_ontimeout,
420                                 network,
421                                 NULL);
422 }
423
424 static int start_acd(struct connman_network *network)
425 {
426         struct connman_service *service;
427         struct connman_ipconfig *ipconfig_ipv4;
428         const char* address;
429         struct in_addr addr;
430
431         remove_ipv4ll_timeout(network);
432
433         service = connman_service_lookup_from_network(network);
434         if (!service)
435                 return -EINVAL;
436
437         ipconfig_ipv4 = __connman_service_get_ip4config(service);
438         if (!ipconfig_ipv4) {
439                 connman_error("Service has no IPv4 configuration");
440                 return -EINVAL;
441         }
442
443         if (!network->acd_host) {
444                 int index;
445
446                 index = __connman_ipconfig_get_index(ipconfig_ipv4);
447                 network->acd_host = acd_host_new(index,
448                                 connman_service_get_dbuspath(service));
449                 if (!network->acd_host) {
450                         connman_error("Could not create ACD data structure");
451                         return -EINVAL;
452                 }
453
454                 acd_host_register_event(network->acd_host,
455                                 ACD_HOST_EVENT_IPV4_AVAILABLE,
456                                 acd_host_ipv4_available, network);
457                 acd_host_register_event(network->acd_host,
458                                 ACD_HOST_EVENT_IPV4_LOST,
459                                 acd_host_ipv4_lost, network);
460                 acd_host_register_event(network->acd_host,
461                                 ACD_HOST_EVENT_IPV4_CONFLICT,
462                                 acd_host_ipv4_conflict, network);
463                 acd_host_register_event(network->acd_host,
464                                 ACD_HOST_EVENT_IPV4_MAXCONFLICT,
465                                 acd_host_ipv4_maxconflict, network);
466         }
467
468         address = __connman_ipconfig_get_local(ipconfig_ipv4);
469         if (!address)
470                 return -EINVAL;
471
472         connman_info("Starting ACD for address %s", address);
473         if (inet_pton(AF_INET, address, &addr) != 1)
474                 connman_error("Could not convert address %s", address);
475
476         acd_host_start(network->acd_host, htonl(addr.s_addr));
477
478         return 0;
479 }
480
481 static void dhcp_success(struct connman_network *network)
482 {
483         struct connman_service *service;
484         struct connman_ipconfig *ipconfig_ipv4;
485         int err;
486
487         service = connman_service_lookup_from_network(network);
488         if (!service)
489                 goto err;
490
491         ipconfig_ipv4 = __connman_service_get_ip4config(service);
492
493         DBG("lease acquired for ipconfig %p", ipconfig_ipv4);
494
495         if (!ipconfig_ipv4)
496                 return;
497
498         if (connman_setting_get_bool("AddressConflictDetection")) {
499                 err = start_acd(network);
500                 if (!err)
501                         return;
502
503                 /* On error proceed without ACD. */
504         }
505
506         err = __connman_ipconfig_address_add(ipconfig_ipv4);
507         if (err < 0)
508                 goto err;
509
510 #if defined TIZEN_EXT
511         err = __connman_ipconfig_gateway_add(ipconfig_ipv4, service);
512 #else
513         err = __connman_ipconfig_gateway_add(ipconfig_ipv4);
514 #endif
515         if (err < 0)
516                 goto err;
517
518         __connman_service_save(service);
519
520         return;
521
522 err:
523         connman_network_set_error(network,
524                                 CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
525 }
526
527 static void dhcp_failure(struct connman_network *network)
528 {
529         struct connman_service *service;
530         struct connman_ipconfig *ipconfig_ipv4;
531
532         service = connman_service_lookup_from_network(network);
533         if (!service)
534                 return;
535
536         ipconfig_ipv4 = __connman_service_get_ip4config(service);
537
538         DBG("lease lost for ipconfig %p", ipconfig_ipv4);
539
540         if (!ipconfig_ipv4)
541                 return;
542
543         __connman_ipconfig_address_remove(ipconfig_ipv4);
544         __connman_ipconfig_gateway_remove(ipconfig_ipv4);
545 }
546
547 static void dhcp_callback(struct connman_ipconfig *ipconfig,
548                         struct connman_network *network,
549                         bool success, gpointer data)
550 {
551         network->connecting = false;
552
553         if (success)
554                 dhcp_success(network);
555         else
556                 dhcp_failure(network);
557 }
558
559 static int set_connected_manual(struct connman_network *network)
560 {
561         int err = 0;
562         struct connman_service *service;
563         struct connman_ipconfig *ipconfig;
564
565         DBG("network %p", network);
566
567         network->connecting = false;
568
569         service = connman_service_lookup_from_network(network);
570         ipconfig = __connman_service_get_ip4config(service);
571         __connman_ipconfig_enable(ipconfig);
572
573 #if defined TIZEN_EXT
574         if (!service || !ipconfig)
575                 return -EINVAL;
576 #endif
577         if (!__connman_ipconfig_get_local(ipconfig))
578                 __connman_service_read_ip4config(service);
579
580         if (connman_setting_get_bool("AddressConflictDetection")) {
581                 err = start_acd(network);
582                 if (!err)
583                         return 0;
584
585                 /* On error proceed without ACD. */
586         }
587
588         err = __connman_ipconfig_address_add(ipconfig);
589         if (err < 0)
590                 goto err;
591
592 #if defined TIZEN_EXT
593         err = __connman_ipconfig_gateway_add(ipconfig, service);
594 #else
595         err = __connman_ipconfig_gateway_add(ipconfig);
596 #endif
597         if (err < 0)
598                 goto err;
599
600 err:
601         return err;
602 }
603
604 static void remove_dhcp_timeout(struct connman_network *network)
605 {
606         if (network->dhcp_timeout > 0) {
607                 g_source_remove(network->dhcp_timeout);
608                 network->dhcp_timeout = 0;
609         }
610 }
611
612 #if defined TIZEN_EXT
613 int set_connected_dhcp(struct connman_network *network)
614 #else
615 static int set_connected_dhcp(struct connman_network *network)
616 #endif
617 {
618         struct connman_service *service;
619         struct connman_ipconfig *ipconfig_ipv4;
620         int err;
621
622         DBG("network %p", network);
623         remove_dhcp_timeout(network);
624
625         service = connman_service_lookup_from_network(network);
626         ipconfig_ipv4 = __connman_service_get_ip4config(service);
627         __connman_ipconfig_enable(ipconfig_ipv4);
628
629         err = __connman_dhcp_start(ipconfig_ipv4, network,
630                                                         dhcp_callback, NULL);
631         if (err < 0) {
632                 connman_error("Can not request DHCP lease");
633                 return err;
634         }
635
636         return 0;
637 }
638
639 static gboolean set_connected_dhcp_timout(gpointer data)
640 {
641         struct connman_network *network = data;
642         struct connman_service *service;
643         struct connman_ipconfig *ipconfig;
644         enum connman_ipconfig_method method;
645
646         network->dhcp_timeout = 0;
647
648         service = connman_service_lookup_from_network(network);
649         if (!service)
650                 return FALSE;
651
652         ipconfig = __connman_service_get_ip4config(service);
653         if (!ipconfig)
654                 return FALSE;
655
656         /* Method is still DHCP? */
657         method = __connman_ipconfig_get_method(ipconfig);
658         if (method == CONNMAN_IPCONFIG_METHOD_DHCP)
659                 set_connected_dhcp(network);
660
661         return FALSE;
662 }
663
664 void connman_network_set_connected_dhcp_later(struct connman_network *network,
665                 uint32_t sec)
666 {
667         remove_dhcp_timeout(network);
668
669         network->dhcp_timeout =
670                 g_timeout_add_seconds_full(G_PRIORITY_HIGH,
671                                 sec,
672                                 set_connected_dhcp_timout,
673                                 network,
674                                 NULL);
675 }
676
677 static int manual_ipv6_set(struct connman_network *network,
678                                 struct connman_ipconfig *ipconfig_ipv6)
679 {
680         struct connman_service *service;
681         int err;
682
683         DBG("network %p ipv6 %p", network, ipconfig_ipv6);
684
685         service = connman_service_lookup_from_network(network);
686         if (!service)
687                 return -EINVAL;
688
689         if (!__connman_ipconfig_get_local(ipconfig_ipv6))
690                 __connman_service_read_ip6config(service);
691
692         __connman_ipconfig_enable_ipv6(ipconfig_ipv6);
693
694         err = __connman_ipconfig_address_add(ipconfig_ipv6);
695         if (err < 0) {
696                 connman_network_set_error(network,
697                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
698                 return err;
699         }
700
701 #if defined TIZEN_EXT
702         err = __connman_ipconfig_gateway_add(ipconfig_ipv6, service);
703 #else
704         err = __connman_ipconfig_gateway_add(ipconfig_ipv6);
705 #endif
706         if (err < 0)
707                 return err;
708
709         __connman_device_set_network(network->device, network);
710
711         connman_network_set_associating(network, false);
712
713         network->connecting = false;
714
715         return 0;
716 }
717
718 static void stop_dhcpv6(struct connman_network *network)
719 {
720         network->connecting = false;
721
722         __connman_dhcpv6_stop(network);
723 }
724
725 static void dhcpv6_release_callback(struct connman_network *network,
726                                 enum __connman_dhcpv6_status status,
727                                 gpointer data)
728 {
729         DBG("status %d", status);
730
731         stop_dhcpv6(network);
732 }
733
734 static void release_dhcpv6(struct connman_network *network)
735 {
736         __connman_dhcpv6_start_release(network, dhcpv6_release_callback);
737         stop_dhcpv6(network);
738 }
739
740 static void dhcpv6_info_callback(struct connman_network *network,
741                                 enum __connman_dhcpv6_status status,
742                                 gpointer data)
743 {
744         DBG("status %d", status);
745
746         stop_dhcpv6(network);
747 }
748
749 static int dhcpv6_set_addresses(struct connman_network *network)
750 {
751         struct connman_service *service;
752         struct connman_ipconfig *ipconfig_ipv6;
753         int err = -EINVAL;
754
755         service = connman_service_lookup_from_network(network);
756         if (!service)
757                 goto err;
758
759         network->connecting = false;
760
761         ipconfig_ipv6 = __connman_service_get_ip6config(service);
762 #if defined TIZEN_EXT
763         if (!ipconfig_ipv6)
764                 goto err;
765 #endif
766         err = __connman_ipconfig_address_add(ipconfig_ipv6);
767         if (err < 0)
768                 goto err;
769
770         return 0;
771
772 err:
773         connman_network_set_error(network,
774                                 CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
775         return err;
776 }
777
778 static void autoconf_ipv6_set(struct connman_network *network);
779 static void dhcpv6_callback(struct connman_network *network,
780                         enum __connman_dhcpv6_status status, gpointer data);
781
782 /*
783  * Have a separate callback for renew so that we do not do autoconf
784  * in wrong phase as the dhcpv6_callback() is also called when doing
785  * DHCPv6 solicitation.
786  */
787 static void dhcpv6_renew_callback(struct connman_network *network,
788                                 enum __connman_dhcpv6_status status,
789                                 gpointer data)
790 {
791         switch (status) {
792         case CONNMAN_DHCPV6_STATUS_SUCCEED:
793                 dhcpv6_callback(network, status, data);
794                 break;
795         case CONNMAN_DHCPV6_STATUS_FAIL:
796         case CONNMAN_DHCPV6_STATUS_RESTART:
797                 stop_dhcpv6(network);
798
799                 /* restart and do solicit again. */
800                 autoconf_ipv6_set(network);
801                 break;
802         }
803 }
804
805 static void dhcpv6_callback(struct connman_network *network,
806                         enum __connman_dhcpv6_status status, gpointer data)
807 {
808         DBG("status %d", status);
809
810         /* Start the renew process if necessary */
811         if (status == CONNMAN_DHCPV6_STATUS_SUCCEED) {
812
813                 if (dhcpv6_set_addresses(network) < 0) {
814                         stop_dhcpv6(network);
815                         return;
816                 }
817
818                 if (__connman_dhcpv6_start_renew(network,
819                                         dhcpv6_renew_callback) == -ETIMEDOUT)
820                         dhcpv6_renew_callback(network,
821                                                 CONNMAN_DHCPV6_STATUS_FAIL,
822                                                 data);
823
824         } else if (status == CONNMAN_DHCPV6_STATUS_RESTART) {
825                 stop_dhcpv6(network);
826                 autoconf_ipv6_set(network);
827         } else
828                 stop_dhcpv6(network);
829 }
830
831 static void check_dhcpv6(struct nd_router_advert *reply,
832                         unsigned int length, void *user_data)
833 {
834         struct connman_network *network = user_data;
835         struct connman_service *service;
836         GSList *prefixes;
837
838         DBG("reply %p", reply);
839
840         if (!reply) {
841                 /*
842                  * Router solicitation message seem to get lost easily so
843                  * try to send it again.
844                  */
845                 if (network->router_solicit_count > 0) {
846                         DBG("re-send router solicitation %d",
847                                                 network->router_solicit_count);
848                         network->router_solicit_count--;
849                         __connman_inet_ipv6_send_rs(network->index, RTR_SOLICITATION_INTERVAL,
850                                                 check_dhcpv6, network);
851                         return;
852                 }
853 #if defined TIZEN_EXT
854                 DBG("RA message is not received from server in reply of RS.");
855 #endif
856                 connman_network_unref(network);
857                 return;
858         }
859
860         network->router_solicit_count = 0;
861
862         /*
863          * If we were disconnected while waiting router advertisement,
864          * we just quit and do not start DHCPv6
865          */
866         if (!network->connected) {
867                 connman_network_unref(network);
868 #if defined TIZEN_EXT
869                 DBG("Network is not connected");
870 #endif
871                 return;
872         }
873
874         prefixes = __connman_inet_ipv6_get_prefixes(reply, length);
875
876         /*
877          * If IPv6 config is missing from service, then create it.
878          * The ipconfig might be missing if we got a rtnl message
879          * that disabled IPv6 config and thus removed it. This
880          * can happen if we are switching from one service to
881          * another in the same interface. The only way to get IPv6
882          * config back is to re-create it here.
883          */
884         service = connman_service_lookup_from_network(network);
885         if (service) {
886                 connman_service_create_ip6config(service, network->index);
887
888                 connman_network_set_associating(network, false);
889
890                 __connman_service_ipconfig_indicate_state(service,
891                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
892                                         CONNMAN_IPCONFIG_TYPE_IPV6);
893         }
894
895         /*
896          * We do stateful/stateless DHCPv6 if router advertisement says so.
897          */
898         if (reply->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) {
899 #if defined TIZEN_EXT
900                 DBG("IPv6 ND_RA_FLAG_MANAGED");
901 #endif
902                 __connman_dhcpv6_start(network, prefixes, dhcpv6_callback);
903         } else {
904                 if (reply->nd_ra_flags_reserved & ND_RA_FLAG_OTHER)
905 #if defined TIZEN_EXT
906                 {
907                         DBG("IPv6 ND_RA_FLAG_OTHER");
908 #endif
909                         __connman_dhcpv6_start_info(network,
910                                                         dhcpv6_info_callback);
911 #if defined TIZEN_EXT
912                 }
913 #endif
914
915                 g_slist_free_full(prefixes, g_free);
916                 network->connecting = false;
917         }
918
919         connman_network_unref(network);
920 }
921
922 static void receive_refresh_rs_reply(struct nd_router_advert *reply,
923                 unsigned int length, void *user_data)
924 {
925         struct connman_network *network = user_data;
926
927         DBG("reply %p", reply);
928
929         if (!reply) {
930                 /*
931                  * Router solicitation message seem to get lost easily so
932                  * try to send it again.
933                  */
934                 if (network->router_solicit_refresh_count > 1) {
935                         network->router_solicit_refresh_count--;
936                         DBG("re-send router solicitation %d",
937                                         network->router_solicit_refresh_count);
938                         __connman_inet_ipv6_send_rs(network->index,
939                                         RS_REFRESH_TIMEOUT,
940                                         receive_refresh_rs_reply,
941                                         network);
942                         return;
943                 }
944         }
945
946         /* RS refresh not in progress anymore */
947         network->router_solicit_refresh_count = 0;
948
949         connman_network_unref(network);
950 }
951
952 int __connman_network_refresh_rs_ipv6(struct connman_network *network,
953                                         int index)
954 {
955         int ret = 0;
956
957         DBG("network %p index %d", network, index);
958
959         /* Send only one RS for all RDNSS entries which are about to expire */
960         if (network->router_solicit_refresh_count > 0) {
961                 DBG("RS refresh already started");
962                 return 0;
963         }
964
965         network->router_solicit_refresh_count = RS_REFRESH_COUNT;
966
967         connman_network_ref(network);
968
969         ret = __connman_inet_ipv6_send_rs(index, RS_REFRESH_TIMEOUT,
970                         receive_refresh_rs_reply, network);
971         return ret;
972 }
973
974 static void autoconf_ipv6_set(struct connman_network *network)
975 {
976         struct connman_service *service;
977         struct connman_ipconfig *ipconfig;
978         int index;
979
980         DBG("network %p", network);
981
982         if (network->router_solicit_count > 0) {
983                 /*
984                  * The autoconfiguration is already pending and we have sent
985                  * router solicitation messages and are now waiting answers.
986                  * There is no need to continue any further.
987                  */
988                 DBG("autoconfiguration already started");
989                 return;
990         }
991
992         __connman_device_set_network(network->device, network);
993
994 #if defined TIZEN_EXT
995         if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR)
996                 return;
997 #endif
998
999         service = connman_service_lookup_from_network(network);
1000         if (!service)
1001                 return;
1002
1003         ipconfig = __connman_service_get_ip6config(service);
1004         if (!ipconfig)
1005                 return;
1006
1007         __connman_ipconfig_enable(ipconfig);
1008
1009         __connman_ipconfig_enable_ipv6(ipconfig);
1010
1011         __connman_ipconfig_address_remove(ipconfig);
1012
1013         index = __connman_ipconfig_get_index(ipconfig);
1014
1015         connman_network_ref(network);
1016
1017         /* Try to get stateless DHCPv6 information, RFC 3736 */
1018         network->router_solicit_count = 3;
1019         __connman_inet_ipv6_send_rs(index, RTR_SOLICITATION_INTERVAL,
1020                         check_dhcpv6, network);
1021 }
1022
1023 static void set_connected(struct connman_network *network)
1024 {
1025         struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
1026         struct connman_service *service;
1027
1028         if (network->connected)
1029                 return;
1030
1031         connman_network_set_associating(network, false);
1032
1033         network->connected = true;
1034
1035         service = connman_service_lookup_from_network(network);
1036
1037         ipconfig_ipv4 = __connman_service_get_ip4config(service);
1038         ipconfig_ipv6 = __connman_service_get_ip6config(service);
1039
1040         DBG("service %p ipv4 %p ipv6 %p", service, ipconfig_ipv4,
1041                 ipconfig_ipv6);
1042
1043         __connman_network_enable_ipconfig(network, ipconfig_ipv4);
1044         __connman_network_enable_ipconfig(network, ipconfig_ipv6);
1045 }
1046
1047 static void set_disconnected(struct connman_network *network)
1048 {
1049         struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
1050         enum connman_ipconfig_method ipv4_method, ipv6_method;
1051         enum connman_service_state state;
1052         struct connman_service *service;
1053
1054         service = connman_service_lookup_from_network(network);
1055
1056         ipconfig_ipv4 = __connman_service_get_ip4config(service);
1057         ipconfig_ipv6 = __connman_service_get_ip6config(service);
1058
1059         DBG("service %p ipv4 %p ipv6 %p", service, ipconfig_ipv4,
1060                 ipconfig_ipv6);
1061
1062         ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4);
1063         ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6);
1064
1065         DBG("method ipv4 %d ipv6 %d", ipv4_method, ipv6_method);
1066
1067         /*
1068          * Resetting solicit count here will prevent the RS resend loop
1069          * from sending packets in check_dhcpv6()
1070          */
1071         network->router_solicit_count = 0;
1072
1073         __connman_device_set_network(network->device, NULL);
1074
1075         if (network->connected) {
1076                 switch (ipv6_method) {
1077                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1078                 case CONNMAN_IPCONFIG_METHOD_OFF:
1079                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1080                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1081                         break;
1082                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1083                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1084                         release_dhcpv6(network);
1085                         break;
1086                 }
1087
1088                 switch (ipv4_method) {
1089                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1090                 case CONNMAN_IPCONFIG_METHOD_OFF:
1091                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1092                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1093                         break;
1094                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1095                         /*
1096                          * If the current method is AUTO then next time we
1097                          * try first DHCP. DHCP also needs to be stopped
1098                          * in this case because if we fell in AUTO means
1099                          * that DHCP  was launched for IPv4 but it failed.
1100                          */
1101                         __connman_ipconfig_set_method(ipconfig_ipv4,
1102                                                 CONNMAN_IPCONFIG_METHOD_DHCP);
1103                         __connman_service_notify_ipv4_configuration(service);
1104                         /* fall through */
1105                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1106                         remove_dhcp_timeout(network);
1107                         __connman_dhcp_stop(ipconfig_ipv4);
1108                         break;
1109                 }
1110         }
1111
1112         /*
1113          * We only set the disconnect state if we were not in idle
1114          * or in failure. It does not make sense to go to disconnect
1115          * state if we were not connected.
1116          */
1117         state = __connman_service_ipconfig_get_state(service,
1118                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1119         if (state != CONNMAN_SERVICE_STATE_IDLE &&
1120                         state != CONNMAN_SERVICE_STATE_FAILURE)
1121                 __connman_service_ipconfig_indicate_state(service,
1122                                         CONNMAN_SERVICE_STATE_DISCONNECT,
1123                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1124
1125         state = __connman_service_ipconfig_get_state(service,
1126                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1127         if (state != CONNMAN_SERVICE_STATE_IDLE &&
1128                                 state != CONNMAN_SERVICE_STATE_FAILURE)
1129                 __connman_service_ipconfig_indicate_state(service,
1130                                         CONNMAN_SERVICE_STATE_DISCONNECT,
1131                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1132
1133         if (network->connected) {
1134 #if defined TIZEN_EXT
1135                 /**
1136                  * Do not remove gateway and its address,
1137                  * if there are connected profiles that use same interface (multiple PDN)
1138                  */
1139                 if (connman_service_get_type(service) != CONNMAN_SERVICE_TYPE_CELLULAR ||
1140                                 __connman_service_get_connected_count_of_iface(service) <= 0) {
1141 #endif
1142                 __connman_connection_gateway_remove(service,
1143                                                 CONNMAN_IPCONFIG_TYPE_ALL);
1144
1145                 __connman_ipconfig_address_unset(ipconfig_ipv4);
1146                 __connman_ipconfig_address_unset(ipconfig_ipv6);
1147
1148 #if defined TIZEN_EXT
1149                 }
1150 #endif
1151                 /*
1152                  * Special handling for IPv6 autoconfigured address.
1153                  * The simplest way to remove autoconfigured routes is to
1154                  * disable IPv6 temporarily so that kernel will do the cleanup
1155                  * automagically.
1156                  */
1157                 if (ipv6_method == CONNMAN_IPCONFIG_METHOD_AUTO) {
1158                         __connman_ipconfig_disable_ipv6(ipconfig_ipv6);
1159                         __connman_ipconfig_enable_ipv6(ipconfig_ipv6);
1160                 }
1161         }
1162
1163         __connman_service_ipconfig_indicate_state(service,
1164                                                 CONNMAN_SERVICE_STATE_IDLE,
1165                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1166
1167         __connman_service_ipconfig_indicate_state(service,
1168                                                 CONNMAN_SERVICE_STATE_IDLE,
1169                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1170
1171         network->connecting = false;
1172         network->connected = false;
1173
1174         connman_network_set_associating(network, false);
1175 }
1176
1177
1178
1179 static int network_probe(struct connman_network *network)
1180 {
1181         GSList *list;
1182         struct connman_network_driver *driver = NULL;
1183
1184         DBG("network %p name %s", network, network->name);
1185
1186         if (network->driver)
1187                 return -EALREADY;
1188
1189         for (list = driver_list; list; list = list->next) {
1190                 driver = list->data;
1191
1192                 if (!match_driver(network, driver)) {
1193                         driver = NULL;
1194                         continue;
1195                 }
1196 #if defined TIZEN_EXT
1197                 if (!simplified_log)
1198 #endif
1199                 DBG("driver %p name %s", driver, driver->name);
1200
1201                 if (driver->probe(network) == 0)
1202                         break;
1203
1204                 driver = NULL;
1205         }
1206
1207         if (!driver)
1208                 return -ENODEV;
1209
1210         if (!network->group)
1211                 return -EINVAL;
1212
1213         switch (network->type) {
1214         case CONNMAN_NETWORK_TYPE_UNKNOWN:
1215         case CONNMAN_NETWORK_TYPE_VENDOR:
1216                 return 0;
1217         case CONNMAN_NETWORK_TYPE_ETHERNET:
1218         case CONNMAN_NETWORK_TYPE_GADGET:
1219         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
1220         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
1221         case CONNMAN_NETWORK_TYPE_CELLULAR:
1222         case CONNMAN_NETWORK_TYPE_WIFI:
1223                 network->driver = driver;
1224                 if (!__connman_service_create_from_network(network)) {
1225                         network->driver = NULL;
1226                         return -EINVAL;
1227                 }
1228         }
1229
1230         return 0;
1231 }
1232
1233 static void network_remove(struct connman_network *network)
1234 {
1235         DBG("network %p name %s", network, network->name);
1236
1237         if (!network->driver)
1238                 return;
1239
1240         if (network->connected)
1241                 set_disconnected(network);
1242
1243         switch (network->type) {
1244         case CONNMAN_NETWORK_TYPE_UNKNOWN:
1245         case CONNMAN_NETWORK_TYPE_VENDOR:
1246                 break;
1247         case CONNMAN_NETWORK_TYPE_ETHERNET:
1248         case CONNMAN_NETWORK_TYPE_GADGET:
1249         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
1250         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
1251         case CONNMAN_NETWORK_TYPE_CELLULAR:
1252         case CONNMAN_NETWORK_TYPE_WIFI:
1253                 if (network->group) {
1254                         __connman_service_remove_from_network(network);
1255
1256                         g_free(network->group);
1257                         network->group = NULL;
1258                 }
1259                 break;
1260         }
1261
1262         if (network->driver->remove)
1263                 network->driver->remove(network);
1264
1265         network->driver = NULL;
1266 }
1267
1268 static void probe_driver(struct connman_network_driver *driver)
1269 {
1270         GSList *list;
1271
1272         DBG("driver %p name %s", driver, driver->name);
1273
1274         for (list = network_list; list; list = list->next) {
1275                 struct connman_network *network = list->data;
1276
1277                 if (network->driver)
1278                         continue;
1279
1280                 if (driver->type != network->type)
1281                         continue;
1282
1283                 if (driver->probe(network) < 0)
1284                         continue;
1285
1286                 network->driver = driver;
1287         }
1288 }
1289
1290 static gint compare_priority(gconstpointer a, gconstpointer b)
1291 {
1292         const struct connman_network_driver *driver1 = a;
1293         const struct connman_network_driver *driver2 = b;
1294
1295         return driver2->priority - driver1->priority;
1296 }
1297
1298 /**
1299  * connman_network_driver_register:
1300  * @driver: network driver definition
1301  *
1302  * Register a new network driver
1303  *
1304  * Returns: %0 on success
1305  */
1306 int connman_network_driver_register(struct connman_network_driver *driver)
1307 {
1308         DBG("driver %p name %s", driver, driver->name);
1309
1310         driver_list = g_slist_insert_sorted(driver_list, driver,
1311                                                         compare_priority);
1312
1313         probe_driver(driver);
1314
1315         return 0;
1316 }
1317
1318 /**
1319  * connman_network_driver_unregister:
1320  * @driver: network driver definition
1321  *
1322  * Remove a previously registered network driver
1323  */
1324 void connman_network_driver_unregister(struct connman_network_driver *driver)
1325 {
1326         GSList *list;
1327
1328         DBG("driver %p name %s", driver, driver->name);
1329
1330         driver_list = g_slist_remove(driver_list, driver);
1331
1332         for (list = network_list; list; list = list->next) {
1333                 struct connman_network *network = list->data;
1334
1335                 if (network->driver == driver)
1336                         network_remove(network);
1337         }
1338 }
1339
1340 static void network_destruct(struct connman_network *network)
1341 {
1342         DBG("network %p name %s", network, network->name);
1343
1344         g_free(network->wifi.ssid);
1345         g_free(network->wifi.mode);
1346         g_free(network->wifi.security);
1347         g_free(network->wifi.passphrase);
1348         g_free(network->wifi.eap);
1349         g_free(network->wifi.identity);
1350         g_free(network->wifi.anonymous_identity);
1351         g_free(network->wifi.agent_identity);
1352         g_free(network->wifi.ca_cert_path);
1353         g_free(network->wifi.subject_match);
1354         g_free(network->wifi.altsubject_match);
1355         g_free(network->wifi.domain_suffix_match);
1356         g_free(network->wifi.domain_match);
1357         g_free(network->wifi.client_cert_path);
1358         g_free(network->wifi.private_key_path);
1359         g_free(network->wifi.private_key_passphrase);
1360         g_free(network->wifi.phase2_auth);
1361         g_free(network->wifi.pin_wps);
1362
1363 #if defined TIZEN_EXT
1364         g_slist_free_full(network->wifi.vsie_list, g_free);
1365         g_slist_free_full(network->wifi.bssid_list, g_free);
1366         g_hash_table_destroy(network->wifi.assoc_reject_table);
1367 #endif
1368         g_free(network->path);
1369         g_free(network->group);
1370         g_free(network->node);
1371         g_free(network->name);
1372         g_free(network->identifier);
1373         acd_host_free(network->acd_host);
1374
1375         network->device = NULL;
1376
1377         g_free(network);
1378 }
1379
1380 /**
1381  * connman_network_create:
1382  * @identifier: network identifier (for example an unique name)
1383  *
1384  * Allocate a new network and assign the #identifier to it.
1385  *
1386  * Returns: a newly-allocated #connman_network structure
1387  */
1388 struct connman_network *connman_network_create(const char *identifier,
1389                                                 enum connman_network_type type)
1390 {
1391         struct connman_network *network;
1392         char *ident;
1393
1394         network = g_try_new0(struct connman_network, 1);
1395         if (!network)
1396                 return NULL;
1397
1398         network->refcount = 1;
1399
1400         ident = g_strdup(identifier);
1401
1402         if (!ident) {
1403                 g_free(network);
1404                 return NULL;
1405         }
1406
1407         network->type       = type;
1408         network->identifier = ident;
1409         network->acd_host = NULL;
1410         network->ipv4ll_timeout = 0;
1411
1412         network_list = g_slist_prepend(network_list, network);
1413
1414         network->dhcp_timeout = 0;
1415
1416         DBG("network %p identifier %s type %s", network, identifier,
1417                 type2string(type));
1418         return network;
1419 }
1420
1421 /**
1422  * connman_network_ref:
1423  * @network: network structure
1424  *
1425  * Increase reference counter of  network
1426  */
1427 struct connman_network *
1428 connman_network_ref_debug(struct connman_network *network,
1429                         const char *file, int line, const char *caller)
1430 {
1431 #if defined TIZEN_EXT
1432         if (!simplified_log)
1433 #endif
1434         DBG("%p name %s ref %d by %s:%d:%s()", network, network->name,
1435                 network->refcount + 1, file, line, caller);
1436
1437         __sync_fetch_and_add(&network->refcount, 1);
1438
1439         return network;
1440 }
1441
1442 /**
1443  * connman_network_unref:
1444  * @network: network structure
1445  *
1446  * Decrease reference counter of network
1447  */
1448 void connman_network_unref_debug(struct connman_network *network,
1449                                 const char *file, int line, const char *caller)
1450 {
1451 #if defined TIZEN_EXT
1452         if (!simplified_log)
1453 #endif
1454         DBG("%p name %s ref %d by %s:%d:%s()", network, network->name,
1455                 network->refcount - 1, file, line, caller);
1456
1457         if (__sync_fetch_and_sub(&network->refcount, 1) != 1)
1458                 return;
1459
1460         network_list = g_slist_remove(network_list, network);
1461
1462         network_destruct(network);
1463 }
1464
1465 const char *__connman_network_get_type(struct connman_network *network)
1466 {
1467         return type2string(network->type);
1468 }
1469
1470 /**
1471  * connman_network_get_type:
1472  * @network: network structure
1473  *
1474  * Get type of network
1475  */
1476 enum connman_network_type connman_network_get_type(
1477                                 struct connman_network *network)
1478 {
1479         return network->type;
1480 }
1481
1482 /**
1483  * connman_network_get_identifier:
1484  * @network: network structure
1485  *
1486  * Get identifier of network
1487  */
1488 const char *connman_network_get_identifier(struct connman_network *network)
1489 {
1490         return network->identifier;
1491 }
1492
1493 /**
1494  * connman_network_set_index:
1495  * @network: network structure
1496  * @index: index number
1497  *
1498  * Set index number of network
1499  */
1500 void connman_network_set_index(struct connman_network *network, int index)
1501 {
1502         struct connman_service *service;
1503         struct connman_ipconfig *ipconfig;
1504
1505         service = connman_service_lookup_from_network(network);
1506         if (!service)
1507                 goto done;
1508
1509         ipconfig = __connman_service_get_ip4config(service);
1510         if (ipconfig) {
1511                 __connman_ipconfig_set_index(ipconfig, index);
1512
1513                 DBG("index %d service %p ip4config %p", network->index,
1514                         service, ipconfig);
1515         }
1516
1517         ipconfig = __connman_service_get_ip6config(service);
1518         if (ipconfig) {
1519                 __connman_ipconfig_set_index(ipconfig, index);
1520
1521                 DBG("index %d service %p ip6config %p", network->index,
1522                         service, ipconfig);
1523         }
1524
1525 done:
1526         network->index = index;
1527 }
1528
1529 /**
1530  * connman_network_get_index:
1531  * @network: network structure
1532  *
1533  * Get index number of network
1534  */
1535 int connman_network_get_index(struct connman_network *network)
1536 {
1537         return network->index;
1538 }
1539
1540 /**
1541  * connman_network_set_group:
1542  * @network: network structure
1543  * @group: group name
1544  *
1545  * Set group name for automatic clustering
1546  */
1547 void connman_network_set_group(struct connman_network *network,
1548                                                         const char *group)
1549 {
1550         switch (network->type) {
1551         case CONNMAN_NETWORK_TYPE_UNKNOWN:
1552         case CONNMAN_NETWORK_TYPE_VENDOR:
1553                 return;
1554         case CONNMAN_NETWORK_TYPE_ETHERNET:
1555         case CONNMAN_NETWORK_TYPE_GADGET:
1556         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
1557         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
1558         case CONNMAN_NETWORK_TYPE_CELLULAR:
1559         case CONNMAN_NETWORK_TYPE_WIFI:
1560                 break;
1561         }
1562
1563         if (g_strcmp0(network->group, group) == 0) {
1564                 if (group)
1565                         __connman_service_update_from_network(network);
1566                 return;
1567         }
1568
1569         if (network->group) {
1570                 __connman_service_remove_from_network(network);
1571
1572                 g_free(network->group);
1573         }
1574
1575         network->group = g_strdup(group);
1576
1577         if (network->group)
1578                 network_probe(network);
1579 }
1580
1581 /**
1582  * connman_network_get_group:
1583  * @network: network structure
1584  *
1585  * Get group name for automatic clustering
1586  */
1587 const char *connman_network_get_group(struct connman_network *network)
1588 {
1589         return network->group;
1590 }
1591
1592 const char *__connman_network_get_ident(struct connman_network *network)
1593 {
1594         if (!network->device)
1595                 return NULL;
1596
1597         return connman_device_get_ident(network->device);
1598 }
1599
1600 bool __connman_network_get_weakness(struct connman_network *network)
1601 {
1602         switch (network->type) {
1603         case CONNMAN_NETWORK_TYPE_UNKNOWN:
1604         case CONNMAN_NETWORK_TYPE_VENDOR:
1605         case CONNMAN_NETWORK_TYPE_ETHERNET:
1606         case CONNMAN_NETWORK_TYPE_GADGET:
1607         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
1608         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
1609         case CONNMAN_NETWORK_TYPE_CELLULAR:
1610                 break;
1611         case CONNMAN_NETWORK_TYPE_WIFI:
1612                 if (network->strength > 0 && network->strength < 20)
1613                         return true;
1614                 break;
1615         }
1616
1617         return false;
1618 }
1619
1620 #if defined TIZEN_EXT
1621 void connman_network_set_connecting(struct connman_network *network)
1622 {
1623         DBG("set network connecting true");
1624         network->connecting = TRUE;
1625         return;
1626 }
1627 #endif
1628
1629 bool connman_network_get_connecting(struct connman_network *network)
1630 {
1631         return network->connecting;
1632 }
1633
1634 /**
1635  * connman_network_set_available:
1636  * @network: network structure
1637  * @available: availability state
1638  *
1639  * Change availability state of network (in range)
1640  */
1641 int connman_network_set_available(struct connman_network *network,
1642                                                 bool available)
1643 {
1644 #if !defined TIZEN_EXT
1645         DBG("network %p available %d", network, available);
1646 #endif
1647
1648         if (network->available == available)
1649                 return -EALREADY;
1650
1651         network->available = available;
1652
1653         return 0;
1654 }
1655
1656 /**
1657  * connman_network_get_available:
1658  * @network: network structure
1659  *
1660  * Get network available setting
1661  */
1662 bool connman_network_get_available(struct connman_network *network)
1663 {
1664         return network->available;
1665 }
1666
1667 #if defined TIZEN_EXT
1668 void connman_network_clear_associating(struct connman_network *network)
1669 {
1670         struct connman_service *service;
1671         enum connman_service_state state;
1672
1673         DBG("network %p", network);
1674
1675         network->connecting = FALSE;
1676         network->associating = FALSE;
1677
1678         service = connman_service_lookup_from_network(network);
1679         if (!service)
1680                 return;
1681
1682         state = __connman_service_ipconfig_get_state(service,
1683                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1684         if (state != CONNMAN_SERVICE_STATE_IDLE &&
1685                         state != CONNMAN_SERVICE_STATE_FAILURE)
1686                 __connman_service_ipconfig_indicate_state(service,
1687                                         CONNMAN_SERVICE_STATE_DISCONNECT,
1688                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1689
1690         state = __connman_service_ipconfig_get_state(service,
1691                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1692         if (state != CONNMAN_SERVICE_STATE_IDLE &&
1693                                 state != CONNMAN_SERVICE_STATE_FAILURE)
1694                 __connman_service_ipconfig_indicate_state(service,
1695                                         CONNMAN_SERVICE_STATE_DISCONNECT,
1696                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1697
1698         __connman_service_ipconfig_indicate_state(service,
1699                                                 CONNMAN_SERVICE_STATE_IDLE,
1700                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1701
1702         __connman_service_ipconfig_indicate_state(service,
1703                                                 CONNMAN_SERVICE_STATE_IDLE,
1704                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1705 }
1706
1707 static gboolean __connman_network_clear_associating_delayed(gpointer user_data)
1708 {
1709         GSList *list;
1710         gboolean found = FALSE;
1711         enum connman_service_state state_ipv4;
1712         enum connman_service_state state_ipv6;
1713         struct connman_service *service;
1714         struct connman_network *network = (struct connman_network *)user_data;
1715
1716         for (list = network_list; list != NULL; list = list->next) {
1717                 struct connman_network *item = list->data;
1718
1719                 if (item == network) {
1720                         found = TRUE;
1721                         break;
1722                 }
1723         }
1724
1725         if (found != TRUE)
1726                 return FALSE;
1727
1728         DBG("network %p name %s", network, network->name);
1729         service = connman_service_lookup_from_network(network);
1730
1731         state_ipv4 = __connman_service_ipconfig_get_state(service,
1732                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1733         state_ipv6 = __connman_service_ipconfig_get_state(service,
1734                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1735
1736         DBG("service %p state %d/%d", service, state_ipv4, state_ipv6);
1737
1738         if (network->associating == FALSE &&
1739                         state_ipv4 == CONNMAN_SERVICE_STATE_ASSOCIATION &&
1740                         state_ipv6 == CONNMAN_SERVICE_STATE_ASSOCIATION) {
1741                 __connman_service_ipconfig_indicate_state(service,
1742                                 CONNMAN_SERVICE_STATE_IDLE,
1743                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1744                 __connman_service_ipconfig_indicate_state(service,
1745                                 CONNMAN_SERVICE_STATE_IDLE,
1746                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1747         } else {
1748                 if (network->associating == FALSE) {
1749                         struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
1750                         enum connman_ipconfig_method ipv4_method, ipv6_method;
1751
1752                         ipconfig_ipv4 = __connman_service_get_ip4config(service);
1753                         ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4);
1754                         ipconfig_ipv6 = __connman_service_get_ip4config(service);
1755                         ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6);
1756
1757                         if((ipv4_method == CONNMAN_IPCONFIG_METHOD_UNKNOWN || ipv4_method == CONNMAN_IPCONFIG_METHOD_OFF) &&
1758                                         (state_ipv6 == CONNMAN_SERVICE_STATE_ASSOCIATION))
1759                                 __connman_service_ipconfig_indicate_state(service,
1760                                                 CONNMAN_SERVICE_STATE_IDLE,
1761                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1762                         if((ipv6_method == CONNMAN_IPCONFIG_METHOD_UNKNOWN || ipv6_method == CONNMAN_IPCONFIG_METHOD_OFF) &&
1763                                         (state_ipv4 == CONNMAN_SERVICE_STATE_ASSOCIATION))
1764                                 __connman_service_ipconfig_indicate_state(service,
1765                                                 CONNMAN_SERVICE_STATE_IDLE,
1766                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1767                 }
1768         }
1769
1770         return FALSE;
1771 }
1772 #endif
1773
1774 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
1775 bool connman_network_check_validity(struct connman_network *network)
1776 {
1777         return (NULL == g_slist_find(network_list, network)) ? false : true;
1778 }
1779 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
1780
1781 /**
1782  * connman_network_set_associating:
1783  * @network: network structure
1784  * @associating: associating state
1785  *
1786  * Change associating state of network
1787  */
1788 int connman_network_set_associating(struct connman_network *network,
1789                                                 bool associating)
1790 {
1791         DBG("network %p associating %d", network, associating);
1792
1793         if (network->associating == associating)
1794                 return -EALREADY;
1795
1796         network->associating = associating;
1797
1798         if (associating) {
1799                 struct connman_service *service;
1800
1801                 service = connman_service_lookup_from_network(network);
1802                 __connman_service_ipconfig_indicate_state(service,
1803                                         CONNMAN_SERVICE_STATE_ASSOCIATION,
1804                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1805                 __connman_service_ipconfig_indicate_state(service,
1806                                         CONNMAN_SERVICE_STATE_ASSOCIATION,
1807                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1808         }
1809
1810 #if defined TIZEN_EXT
1811         if (associating == FALSE &&
1812                         connman_network_get_bool(network, "WiFi.UseWPS") == FALSE)
1813                 g_timeout_add_seconds(1,
1814                                 __connman_network_clear_associating_delayed,
1815                                 network);
1816 #endif
1817
1818         return 0;
1819 }
1820
1821 #if defined TIZEN_EXT
1822 static void set_authenticate_error(struct connman_network *network)
1823 {
1824         struct connman_service *service;
1825
1826         service = connman_service_lookup_from_network(network);
1827
1828         if (!service)
1829                 return;
1830
1831         if (connman_service_get_favorite(service)) {
1832                 __connman_service_set_ignore(service, true);
1833         }
1834
1835         __connman_service_indicate_error(service,
1836                                         CONNMAN_SERVICE_ERROR_AUTH_FAILED);
1837 }
1838 #endif
1839
1840
1841 static void set_associate_error(struct connman_network *network)
1842 {
1843         struct connman_service *service;
1844
1845         service = connman_service_lookup_from_network(network);
1846
1847 #if defined TIZEN_EXT
1848         if (!service)
1849                 return;
1850
1851         if (connman_service_get_favorite(service))
1852                 __connman_service_set_ignore(service, true);
1853
1854         __connman_service_indicate_error(service,
1855                                         CONNMAN_SERVICE_ERROR_ASSOC_FAILED);
1856 #else
1857         __connman_service_indicate_error(service,
1858                                         CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
1859 #endif
1860 }
1861
1862 static void set_configure_error(struct connman_network *network)
1863 {
1864         struct connman_service *service;
1865
1866         service = connman_service_lookup_from_network(network);
1867
1868         __connman_service_indicate_error(service,
1869                                         CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
1870 }
1871
1872 static void set_invalid_key_error(struct connman_network *network)
1873 {
1874         struct connman_service *service;
1875
1876         service = connman_service_lookup_from_network(network);
1877
1878 #if defined TIZEN_EXT
1879         if (service)
1880                 __connman_service_set_favorite(service, false);
1881 #endif
1882         __connman_service_indicate_error(service,
1883                                         CONNMAN_SERVICE_ERROR_INVALID_KEY);
1884 }
1885
1886 static void set_connect_error(struct connman_network *network)
1887 {
1888         struct connman_service *service;
1889
1890         service = connman_service_lookup_from_network(network);
1891
1892         __connman_service_indicate_error(service,
1893                                         CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
1894 }
1895
1896 static void set_blocked_error(struct connman_network *network)
1897 {
1898         struct connman_service *service;
1899
1900         service = connman_service_lookup_from_network(network);
1901
1902         __connman_service_indicate_error(service,
1903                                         CONNMAN_SERVICE_ERROR_BLOCKED);
1904 }
1905
1906
1907 #if defined TIZEN_EXT
1908 static void set_dhcp_error(struct connman_network *network)
1909 {
1910         struct connman_service *service;
1911
1912         if (network->associating != FALSE)
1913                 network->associating = FALSE;
1914
1915         service = connman_service_lookup_from_network(network);
1916
1917         __connman_service_indicate_error(service,
1918                                         CONNMAN_SERVICE_ERROR_DHCP_FAILED);
1919 }
1920 #endif
1921
1922 void connman_network_set_ipv4_method(struct connman_network *network,
1923                                         enum connman_ipconfig_method method)
1924 {
1925         struct connman_service *service;
1926         struct connman_ipconfig *ipconfig;
1927
1928         service = connman_service_lookup_from_network(network);
1929         if (!service)
1930                 return;
1931
1932         ipconfig = __connman_service_get_ip4config(service);
1933         if (!ipconfig)
1934                 return;
1935
1936         __connman_ipconfig_set_method(ipconfig, method);
1937 }
1938
1939 void connman_network_set_ipv6_method(struct connman_network *network,
1940                                         enum connman_ipconfig_method method)
1941 {
1942         struct connman_service *service;
1943         struct connman_ipconfig *ipconfig;
1944
1945         service = connman_service_lookup_from_network(network);
1946         if (!service)
1947                 return;
1948
1949         ipconfig = __connman_service_get_ip6config(service);
1950         if (!ipconfig)
1951                 return;
1952
1953         __connman_ipconfig_set_method(ipconfig, method);
1954 }
1955
1956 void connman_network_set_error(struct connman_network *network,
1957                                         enum connman_network_error error)
1958 {
1959         DBG("network %p error %d", network, error);
1960
1961         switch (error) {
1962         case CONNMAN_NETWORK_ERROR_UNKNOWN:
1963                 return;
1964         case CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL:
1965                 set_associate_error(network);
1966                 break;
1967         case CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL:
1968                 set_configure_error(network);
1969                 break;
1970         case CONNMAN_NETWORK_ERROR_INVALID_KEY:
1971                 set_invalid_key_error(network);
1972                 break;
1973         case CONNMAN_NETWORK_ERROR_CONNECT_FAIL:
1974                 set_connect_error(network);
1975                 break;
1976 #if defined TIZEN_EXT
1977         case CONNMAN_NETWORK_ERROR_AUTHENTICATE_FAIL:
1978                 set_authenticate_error(network);
1979                 break;
1980         case CONNMAN_NETWORK_ERROR_DHCP_FAIL:
1981                 set_dhcp_error(network);
1982                 break;
1983 #endif
1984
1985         case CONNMAN_NETWORK_ERROR_BLOCKED:
1986                 set_blocked_error(network);
1987                 break;
1988         }
1989
1990         __connman_network_disconnect(network);
1991 }
1992
1993 /**
1994  * connman_network_set_connected:
1995  * @network: network structure
1996  * @connected: connected state
1997  *
1998  * Change connected state of network
1999  */
2000 int connman_network_set_connected(struct connman_network *network,
2001                                                 bool connected)
2002 {
2003         DBG("network %p connected %d/%d connecting %d associating %d",
2004                 network, network->connected, connected, network->connecting,
2005                 network->associating);
2006
2007         if ((network->connecting || network->associating) &&
2008                                                         !connected) {
2009                 connman_network_set_error(network,
2010                                         CONNMAN_NETWORK_ERROR_CONNECT_FAIL);
2011                 return 0;
2012         }
2013
2014         if (network->connected == connected)
2015                 return -EALREADY;
2016
2017         if (!connected)
2018                 set_disconnected(network);
2019         else
2020                 set_connected(network);
2021
2022         return 0;
2023 }
2024
2025 /**
2026  * connman_network_get_connected:
2027  * @network: network structure
2028  *
2029  * Get network connection status
2030  */
2031 bool connman_network_get_connected(struct connman_network *network)
2032 {
2033         return network->connected;
2034 }
2035
2036 #if defined TIZEN_EXT
2037 bool connman_network_get_psk_sha256(struct connman_network *network)
2038 {
2039         return network->is_psk_sha256;
2040 }
2041
2042 void connman_network_set_psk_sha256(struct connman_network *network, bool is_psk_sha256)
2043 {
2044         network->is_psk_sha256 = is_psk_sha256;
2045 }
2046 #endif
2047
2048 /**
2049  * connman_network_get_associating:
2050  * @network: network structure
2051  *
2052  * Get network associating status
2053  */
2054 bool connman_network_get_associating(struct connman_network *network)
2055 {
2056         return network->associating;
2057 }
2058
2059 void connman_network_clear_hidden(void *user_data)
2060 {
2061         if (!user_data)
2062                 return;
2063
2064         DBG("user_data %p", user_data);
2065
2066         /*
2067          * Hidden service does not have a connect timeout so
2068          * we do not need to remove it. We can just return
2069          * error to the caller telling that we could not find
2070          * any network that we could connect to.
2071          */
2072         connman_dbus_reply_pending(user_data, EIO, NULL);
2073 }
2074
2075 int connman_network_connect_hidden(struct connman_network *network,
2076                         char *identity, char *passphrase, void *user_data)
2077 {
2078         int err = 0;
2079         struct connman_service *service;
2080
2081         service = connman_service_lookup_from_network(network);
2082
2083         DBG("network %p service %p user_data %p", network, service, user_data);
2084
2085         if (!service)
2086                 return -EINVAL;
2087
2088         if (identity)
2089                 __connman_service_set_agent_identity(service, identity);
2090
2091         if (passphrase)
2092                 err = __connman_service_set_passphrase(service, passphrase);
2093
2094         if (err == -ENOKEY) {
2095                 __connman_service_indicate_error(service,
2096                                         CONNMAN_SERVICE_ERROR_INVALID_KEY);
2097                 goto out;
2098         } else {
2099                 __connman_service_set_hidden(service);
2100                 __connman_service_set_hidden_data(service, user_data);
2101                 return __connman_service_connect(service,
2102                                         CONNMAN_SERVICE_CONNECT_REASON_USER);
2103         }
2104
2105 out:
2106         __connman_service_return_error(service, -err, user_data);
2107         return err;
2108 }
2109
2110 #if defined TIZEN_EXT
2111 dbus_bool_t __connman_network_notify_dhcp_changed(const char *key, void *val)
2112 {
2113         int *value = (int *) val;
2114         DBusMessage *signal;
2115         DBusMessageIter iter;
2116         dbus_bool_t result = FALSE;
2117
2118         DBG("key %s, val %d", key, *value);
2119
2120         signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
2121                         CONNMAN_MANAGER_INTERFACE, "DhcpChanged");
2122
2123         if (!signal)
2124                 return result;
2125
2126         dbus_message_iter_init_append(signal, &iter);
2127         connman_dbus_property_append_basic(&iter, key, DBUS_TYPE_INT32, val);
2128
2129         result = dbus_connection_send(connection, signal, NULL);
2130         if (result)
2131                 DBG("Successfuly sent signal");
2132         else
2133                 DBG("Fail to send signal");
2134
2135         dbus_message_unref(signal);
2136
2137         return result;
2138 }
2139 #endif
2140
2141 /**
2142  * __connman_network_connect:
2143  * @network: network structure
2144  *
2145  * Connect network
2146  */
2147 int __connman_network_connect(struct connman_network *network)
2148 {
2149         int err;
2150
2151         DBG("network %p", network);
2152
2153         if (network->connected)
2154                 return -EISCONN;
2155
2156         if (network->connecting || network->associating)
2157                 return -EALREADY;
2158
2159         if (!network->driver)
2160                 return -EUNATCH;
2161
2162         if (!network->driver->connect)
2163                 return -ENOSYS;
2164
2165         if (!network->device)
2166                 return -ENODEV;
2167
2168 #if defined TIZEN_EXT
2169         if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR)
2170 #endif
2171         __connman_device_disconnect(network->device);
2172
2173         network->connecting = true;
2174
2175 #if defined TIZEN_EXT
2176         DBG("ConnMan, Connect Request [%s]", network->name);
2177 #endif
2178
2179         err = network->driver->connect(network);
2180         if (err < 0) {
2181                 if (err == -EINPROGRESS) {
2182 #if defined TIZEN_EXT
2183                         if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR)
2184 #endif
2185                         connman_network_set_associating(network, true);
2186                 } else
2187                         network->connecting = false;
2188
2189                 return err;
2190         }
2191
2192 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
2193         /*
2194          * Note: If EAP on Ethernet is ON, then network will be connected
2195          * after EAP Success event is recieved, from plugin/ethernet.c
2196          */
2197         struct connman_service *service = connman_service_lookup_from_network(network);
2198         if (service && __connman_service_get_use_eapol(service)) {
2199                 connman_network_set_associating(network, true);
2200                 return 0;
2201         }
2202 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
2203
2204         set_connected(network);
2205
2206         return err;
2207 }
2208
2209 /**
2210  * __connman_network_disconnect:
2211  * @network: network structure
2212  *
2213  * Disconnect network
2214  */
2215 int __connman_network_disconnect(struct connman_network *network)
2216 {
2217         int err = 0;
2218 #if defined TIZEN_EXT
2219         if (!simplified_log)
2220 #endif
2221         DBG("network %p", network);
2222
2223         remove_ipv4ll_timeout(network);
2224         if (network->acd_host)
2225                 acd_host_stop(network->acd_host);
2226
2227         if (!network->connected && !network->connecting &&
2228                                                 !network->associating)
2229                 return -ENOTCONN;
2230
2231         if (!network->driver)
2232                 return -EUNATCH;
2233
2234         network->connecting = false;
2235
2236 #if defined TIZEN_EXT
2237         DBG("ConnMan, Disconnect request");
2238         struct connman_service *service = connman_service_lookup_from_network(network);
2239         connman_service_set_disconnection_requested(service, true);
2240 #endif
2241         if (network->driver->disconnect)
2242                 err = network->driver->disconnect(network);
2243
2244         if (err != -EINPROGRESS)
2245                 set_disconnected(network);
2246
2247         return err;
2248 }
2249
2250 int __connman_network_clear_ipconfig(struct connman_network *network,
2251                                         struct connman_ipconfig *ipconfig)
2252 {
2253         struct connman_service *service;
2254         struct connman_ipconfig *ipconfig_ipv4;
2255         enum connman_ipconfig_method method;
2256         enum connman_ipconfig_type type;
2257
2258         service = connman_service_lookup_from_network(network);
2259         if (!service)
2260                 return -EINVAL;
2261
2262         ipconfig_ipv4 = __connman_service_get_ip4config(service);
2263         method = __connman_ipconfig_get_method(ipconfig);
2264         type = __connman_ipconfig_get_config_type(ipconfig);
2265
2266         switch (method) {
2267         case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2268         case CONNMAN_IPCONFIG_METHOD_OFF:
2269         case CONNMAN_IPCONFIG_METHOD_FIXED:
2270                 return -EINVAL;
2271         case CONNMAN_IPCONFIG_METHOD_MANUAL:
2272                 __connman_ipconfig_address_remove(ipconfig);
2273                 break;
2274         case CONNMAN_IPCONFIG_METHOD_AUTO:
2275                 release_dhcpv6(network);
2276                 if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
2277                         break;
2278                 /* fall through */
2279         case CONNMAN_IPCONFIG_METHOD_DHCP:
2280                 remove_dhcp_timeout(network);
2281                 __connman_dhcp_stop(ipconfig_ipv4);
2282                 break;
2283         }
2284
2285         if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
2286                 __connman_service_ipconfig_indicate_state(service,
2287                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
2288                                         CONNMAN_IPCONFIG_TYPE_IPV6);
2289         else if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
2290                 __connman_service_ipconfig_indicate_state(service,
2291                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
2292                                         CONNMAN_IPCONFIG_TYPE_IPV4);
2293
2294         return 0;
2295 }
2296
2297 #if defined TIZEN_EXT
2298 void __connman_network_set_auto_ipv6_gateway(char *gateway, void *user_data)
2299 {
2300         DBG("");
2301
2302         struct connman_network *network = user_data;
2303         struct connman_service *service;
2304         struct connman_ipconfig *ipconfig = NULL;
2305
2306         service = connman_service_lookup_from_network(network);
2307         if (service == NULL)
2308                 return;
2309
2310         ipconfig = __connman_service_get_ipconfig(service, AF_INET6);
2311         if (ipconfig == NULL)
2312                 return;
2313
2314         __connman_ipconfig_set_gateway(ipconfig, gateway);
2315
2316         return;
2317 }
2318 #endif
2319
2320 int __connman_network_enable_ipconfig(struct connman_network *network,
2321                                 struct connman_ipconfig *ipconfig)
2322 {
2323         int r = 0;
2324         enum connman_ipconfig_type type;
2325         enum connman_ipconfig_method method;
2326 #if defined TIZEN_EXT
2327         struct connman_service *service;
2328 #endif
2329
2330         if (!network || !ipconfig)
2331                 return -EINVAL;
2332
2333         type = __connman_ipconfig_get_config_type(ipconfig);
2334
2335         switch (type) {
2336         case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2337         case CONNMAN_IPCONFIG_TYPE_ALL:
2338                 return -ENOSYS;
2339
2340         case CONNMAN_IPCONFIG_TYPE_IPV6:
2341                 set_configuration(network, type);
2342
2343                 method = __connman_ipconfig_get_method(ipconfig);
2344
2345                 DBG("ipv6 ipconfig method %d", method);
2346
2347                 switch (method) {
2348                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2349                         break;
2350
2351                 case CONNMAN_IPCONFIG_METHOD_OFF:
2352                         __connman_ipconfig_disable_ipv6(ipconfig);
2353                         break;
2354
2355                 case CONNMAN_IPCONFIG_METHOD_AUTO:
2356 #if defined TIZEN_EXT
2357                 service = connman_service_lookup_from_network(network);
2358
2359                 if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR)
2360                         __connman_service_ipconfig_indicate_state(service,
2361                                 CONNMAN_SERVICE_STATE_CONFIGURATION,
2362                                         CONNMAN_IPCONFIG_TYPE_IPV6);
2363 #endif
2364                         autoconf_ipv6_set(network);
2365                         break;
2366
2367                 case CONNMAN_IPCONFIG_METHOD_FIXED:
2368                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2369                         r = manual_ipv6_set(network, ipconfig);
2370                         break;
2371
2372                 case CONNMAN_IPCONFIG_METHOD_DHCP:
2373                         r = -ENOSYS;
2374                         break;
2375                 }
2376
2377                 break;
2378
2379         case CONNMAN_IPCONFIG_TYPE_IPV4:
2380                 set_configuration(network, type);
2381
2382                 method = __connman_ipconfig_get_method(ipconfig);
2383
2384                 DBG("ipv4 ipconfig method %d", method);
2385
2386                 switch (method) {
2387                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
2388                 case CONNMAN_IPCONFIG_METHOD_OFF:
2389                         break;
2390
2391                 case CONNMAN_IPCONFIG_METHOD_AUTO:
2392                         r = -ENOSYS;
2393                         break;
2394
2395                 case CONNMAN_IPCONFIG_METHOD_FIXED:
2396                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
2397                         r = set_connected_manual(network);
2398                         break;
2399
2400                 case CONNMAN_IPCONFIG_METHOD_DHCP:
2401                         r = set_connected_dhcp(network);
2402                         break;
2403                 }
2404
2405                 break;
2406         }
2407
2408         if (r < 0)
2409                 connman_network_set_error(network,
2410                                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
2411
2412         return r;
2413 }
2414
2415 int connman_network_set_ipaddress(struct connman_network *network,
2416                                         struct connman_ipaddress *ipaddress)
2417 {
2418         struct connman_service *service;
2419         struct connman_ipconfig *ipconfig = NULL;
2420
2421         DBG("network %p", network);
2422
2423         service = connman_service_lookup_from_network(network);
2424         if (!service)
2425                 return -EINVAL;
2426
2427         ipconfig = __connman_service_get_ipconfig(service, ipaddress->family);
2428         if (!ipconfig)
2429                 return -EINVAL;
2430
2431         __connman_ipconfig_set_local(ipconfig, ipaddress->local);
2432         __connman_ipconfig_set_peer(ipconfig, ipaddress->peer);
2433         __connman_ipconfig_set_broadcast(ipconfig, ipaddress->broadcast);
2434         __connman_ipconfig_set_prefixlen(ipconfig, ipaddress->prefixlen);
2435         __connman_ipconfig_set_gateway(ipconfig, ipaddress->gateway);
2436
2437         return 0;
2438 }
2439
2440 #if defined TIZEN_EXT
2441 /*
2442  * Description: Network client requires additional wifi specific info
2443  */
2444 int connman_network_set_bssid(struct connman_network *network,
2445                                 const unsigned char *bssid)
2446 {
2447         int i = 0;
2448
2449         if (bssid == NULL)
2450                 return -EINVAL;
2451
2452         if (!simplified_log)
2453                 DBG("network %p bssid %02x:%02x:%02x:%02x:%02x:%02x", network,
2454                                 bssid[0], bssid[1], bssid[2],
2455                                 bssid[3], bssid[4], bssid[5]);
2456
2457         for (;i < WIFI_BSSID_LEN_MAX;i++)
2458                 network->wifi.bssid[i] = bssid[i];
2459
2460         return 0;
2461 }
2462
2463 unsigned char *connman_network_get_bssid(struct connman_network *network)
2464 {
2465         return (unsigned char *)network->wifi.bssid;
2466 }
2467
2468 int connman_network_set_transition_mode_bssid(struct connman_network *network,
2469                                 const unsigned char *transition_mode_bssid)
2470 {
2471         int i = 0;
2472
2473         if (transition_mode_bssid == NULL)
2474                 return -EINVAL;
2475
2476         for (;i < WIFI_BSSID_LEN_MAX;i++)
2477                 network->wifi.transition_mode_bssid[i] = transition_mode_bssid[i];
2478
2479         return 0;
2480 }
2481
2482 unsigned char *connman_network_get_transition_mode_bssid(struct connman_network *network)
2483 {
2484         return (unsigned char *)network->wifi.transition_mode_bssid;
2485 }
2486
2487 bool connman_network_check_transition_mode(struct connman_network *network1, struct connman_network *network2)
2488 {
2489
2490         if (network1 == NULL || network2 == NULL)
2491                 return FALSE;
2492
2493         if (network1->wifi.owe_transition_mode == FALSE || network2->wifi.owe_transition_mode == FALSE)
2494                 return FALSE;
2495
2496         if ((memcmp(network1->wifi.bssid, network2->wifi.transition_mode_bssid, WIFI_BSSID_LEN_MAX) == 0)
2497                 && (memcmp(network1->wifi.transition_mode_bssid, network2->wifi.bssid, WIFI_BSSID_LEN_MAX) == 0))
2498                 return TRUE;
2499         else
2500                 return FALSE;
2501 }
2502
2503 int connman_network_set_maxspeed(struct connman_network *network,
2504                                 int maxspeed)
2505 {
2506         network->wifi.maxspeed = maxspeed;
2507         return 0;
2508 }
2509
2510 int connman_network_get_maxspeed(struct connman_network *network)
2511 {
2512         if (!network->driver)
2513                 return 0;
2514
2515         if (network->connected)
2516                 return network->wifi.maxspeed;
2517
2518         return 0;
2519 }
2520
2521 int connman_network_set_sec_list(struct connman_network *network,
2522                                         GSList *sec_list)
2523 {
2524         g_slist_free(network->wifi.sec_list);
2525         network->wifi.sec_list = sec_list;
2526
2527         return 0;
2528 }
2529
2530 void *connman_network_get_sec_list(struct connman_network *network)
2531 {
2532         return network->wifi.sec_list;
2533 }
2534
2535 int connman_network_set_maxrate(struct connman_network *network,
2536                                 unsigned int maxrate)
2537 {
2538 #if !defined TIZEN_EXT
2539         DBG("network %p maxrate %d", network, maxrate);
2540 #endif
2541
2542         network->wifi.maxrate = maxrate;
2543
2544         return 0;
2545 }
2546
2547 unsigned int connman_network_get_maxrate(struct connman_network *network)
2548 {
2549         return network->wifi.maxrate;
2550 }
2551
2552 int connman_network_set_enc_mode(struct connman_network *network,
2553                                 const char *encryption_mode)
2554 {
2555         if (encryption_mode == NULL)
2556                 return -EINVAL;
2557
2558         if (!simplified_log)
2559                 DBG("network %p encryption mode %s", network, encryption_mode);
2560
2561         g_strlcpy(network->wifi.encryption_mode, encryption_mode,
2562                                         WIFI_ENCYPTION_MODE_LEN_MAX);
2563
2564         return 0;
2565 }
2566
2567 const char *connman_network_get_enc_mode(struct connman_network *network)
2568 {
2569         return (const char *)network->wifi.encryption_mode;
2570 }
2571
2572 int connman_network_set_rsn_mode(struct connman_network *network,
2573                                 bool rsn_mode)
2574 {
2575         network->wifi.rsn_mode = rsn_mode;
2576
2577         return 0;
2578 }
2579
2580 int connman_network_set_proxy(struct connman_network *network,
2581                                 const char *proxies)
2582 {
2583         struct connman_service *service;
2584
2585         DBG("network %p proxies %s", network, proxies);
2586
2587         service = connman_service_lookup_from_network(network);
2588         if (service == NULL)
2589                 return -EINVAL;
2590
2591         __connman_service_set_proxy(service, proxies);
2592
2593         connman_service_set_proxy_method(service,
2594                                 CONNMAN_SERVICE_PROXY_METHOD_MANUAL);
2595
2596         return 0;
2597 }
2598
2599 int connman_network_set_keymgmt(struct connman_network *network,
2600                                 unsigned int keymgmt)
2601 {
2602         if (network == NULL)
2603                 return 0;
2604
2605         network->wifi.keymgmt = keymgmt;
2606
2607         return 0;
2608 }
2609
2610 unsigned int connman_network_get_keymgmt(struct connman_network *network)
2611 {
2612         if (network == NULL)
2613                 return 0;
2614
2615         return network->wifi.keymgmt;
2616 }
2617
2618 int connman_network_set_disconnect_reason(struct connman_network *network,
2619                                 int reason_code)
2620 {
2621         if (network == NULL)
2622                 return 0;
2623
2624         network->wifi.disconnect_reason = reason_code;
2625
2626         return 0;
2627 }
2628
2629 int connman_network_get_disconnect_reason(struct connman_network *network)
2630 {
2631         if (network == NULL)
2632                 return 0;
2633
2634         return network->wifi.disconnect_reason;
2635 }
2636 int connman_network_get_assoc_status_code(struct connman_network *network)
2637 {
2638         if (network == NULL)
2639                 return 0;
2640
2641         return network->wifi.assoc_status_code;
2642 }
2643
2644 int connman_network_set_countrycode(struct connman_network *network,
2645                                     const unsigned char *country_code)
2646 {
2647         int i = 0;
2648
2649         if (country_code == NULL)
2650                 return -EINVAL;
2651
2652         if (!simplified_log)
2653                 DBG("network %p Country Code %02x:%02x",network,
2654                                 country_code[0],country_code[1]);
2655
2656         for (; i < WIFI_COUNTRY_CODE_LEN; i++)
2657                 network->wifi.country_code[i] = country_code[i];
2658
2659         return 0;
2660 }
2661
2662 unsigned char *connman_network_get_countrycode(struct connman_network *network)
2663 {
2664         return (unsigned char *)network->wifi.country_code;
2665 }
2666
2667 int connman_network_set_bssid_list(struct connman_network *network,
2668                                         GSList *bssids)
2669 {
2670         unsigned int max_bssid_count;
2671
2672         g_slist_free_full(network->wifi.bssid_list, g_free);
2673         network->wifi.bssid_list = bssids;
2674
2675         max_bssid_count = g_slist_length(bssids);
2676         if (network->wifi.max_bssid_count < max_bssid_count)
2677                 network->wifi.max_bssid_count = max_bssid_count;
2678
2679         return 0;
2680 }
2681
2682 int connman_network_set_phy_mode(struct connman_network *network,
2683                                     ieee80211_modes_e mode)
2684 {
2685         if (!simplified_log)
2686                 DBG("network %p phy mode %d", network, mode);
2687         network->wifi.phy_mode = mode;
2688
2689         return 0;
2690 }
2691
2692 ieee80211_modes_e connman_network_get_phy_mode(struct connman_network *network)
2693 {
2694         return network->wifi.phy_mode;
2695 }
2696
2697 int connman_network_set_connection_mode(struct connman_network *network,
2698                                     connection_mode_e mode)
2699 {
2700         DBG("network %p connection mode %d", network, mode);
2701         network->wifi.connection_mode = mode;
2702
2703         return 0;
2704 }
2705
2706 connection_mode_e connman_network_get_connection_mode(struct connman_network *network)
2707 {
2708         return network->wifi.connection_mode;
2709 }
2710
2711 void *connman_network_get_bssid_list(struct connman_network *network)
2712 {
2713         return network->wifi.bssid_list;
2714 }
2715
2716 unsigned int connman_network_get_max_bssid_count(struct connman_network *network)
2717 {
2718         return network->wifi.max_bssid_count;
2719 }
2720
2721 int connman_network_set_last_connected_bssid(struct connman_network *network,
2722                                 const unsigned char *bssid)
2723 {
2724         if (!bssid)
2725                 return -EINVAL;
2726
2727         if (!memcmp(bssid, invalid_bssid, WIFI_BSSID_LEN_MAX))
2728                 return -EINVAL;
2729
2730         memcpy(network->wifi.last_connected_bssid, bssid, WIFI_BSSID_LEN_MAX);
2731
2732         return 0;
2733 }
2734
2735 unsigned char *connman_network_get_last_connected_bssid(struct connman_network *network)
2736 {
2737         return (unsigned char *)network->wifi.last_connected_bssid;
2738 }
2739
2740 void connman_network_set_assoc_reject_table(struct connman_network *network,
2741                 GHashTable *assoc_reject_table)
2742 {
2743         if (!network)
2744                 return;
2745
2746         if (!assoc_reject_table)
2747                 return;
2748
2749         g_hash_table_destroy(network->wifi.assoc_reject_table);
2750
2751         network->wifi.assoc_reject_table = assoc_reject_table;
2752 }
2753
2754 GHashTable *connman_network_get_assoc_reject_table(struct connman_network *network)
2755 {
2756         if (!network)
2757                 return NULL;
2758
2759         return network->wifi.assoc_reject_table;
2760 }
2761
2762 __time_t connman_network_get_roam_scan_time(struct connman_network *network)
2763 {
2764         return network->wifi.roam_scan_time;
2765 }
2766
2767 void connman_network_set_roam_scan_time(struct connman_network *network,
2768                                                 __time_t roam_scan_time)
2769 {
2770         network->wifi.roam_scan_time = roam_scan_time;
2771 }
2772
2773 int connman_network_get_snr(struct connman_network *network)
2774 {
2775         return network->wifi.snr;
2776 }
2777
2778 void connman_network_set_snr(struct connman_network *network, int snr)
2779 {
2780         network->wifi.snr = snr;
2781 }
2782 #endif
2783
2784 int connman_network_set_nameservers(struct connman_network *network,
2785                                 const char *nameservers)
2786 {
2787         struct connman_service *service;
2788         char **nameservers_array;
2789         int i;
2790
2791         DBG("network %p nameservers %s", network, nameservers);
2792
2793         service = connman_service_lookup_from_network(network);
2794         if (!service)
2795                 return -EINVAL;
2796
2797         __connman_service_nameserver_clear(service);
2798
2799         if (!nameservers)
2800                 return 0;
2801
2802         nameservers_array = g_strsplit(nameservers, " ", 0);
2803
2804         for (i = 0; nameservers_array[i]; i++) {
2805 #if defined TIZEN_EXT
2806                 __connman_service_nameserver_append(service,
2807                                                 nameservers_array[i], false,
2808                                                 CONNMAN_IPCONFIG_TYPE_ALL);
2809 #else
2810                 __connman_service_nameserver_append(service,
2811                                                 nameservers_array[i], false);
2812 #endif
2813         }
2814
2815         g_strfreev(nameservers_array);
2816
2817         return 0;
2818 }
2819
2820 int connman_network_set_domain(struct connman_network *network,
2821                                 const char *domain)
2822 {
2823         struct connman_service *service;
2824
2825         DBG("network %p domain %s", network, domain);
2826
2827         service = connman_service_lookup_from_network(network);
2828         if (!service)
2829                 return -EINVAL;
2830
2831         __connman_service_set_domainname(service, domain);
2832
2833         return 0;
2834 }
2835
2836 /**
2837  * connman_network_set_name:
2838  * @network: network structure
2839  * @name: name value
2840  *
2841  * Set display name value for network
2842  */
2843 int connman_network_set_name(struct connman_network *network,
2844                                                         const char *name)
2845 {
2846 #if defined TIZEN_EXT
2847         if (!simplified_log)
2848 #endif
2849         DBG("network %p name %s", network, name);
2850
2851         g_free(network->name);
2852         network->name = g_strdup(name);
2853
2854         return 0;
2855 }
2856
2857 /**
2858  * connman_network_set_strength:
2859  * @network: network structure
2860  * @strength: strength value
2861  *
2862  * Set signal strength value for network
2863  */
2864
2865 int connman_network_set_strength(struct connman_network *network,
2866                                                 uint8_t strength)
2867 {
2868         network->strength = strength;
2869 #if defined TIZEN_EXT
2870         __connman_service_notify_strength_changed(network);
2871 #endif
2872
2873         return 0;
2874 }
2875
2876 uint8_t connman_network_get_strength(struct connman_network *network)
2877 {
2878         return network->strength;
2879 }
2880
2881 int connman_network_set_frequency(struct connman_network *network,
2882                                                 uint16_t frequency)
2883 {
2884         network->frequency = frequency;
2885
2886         return 0;
2887 }
2888
2889 uint16_t connman_network_get_frequency(struct connman_network *network)
2890 {
2891         return network->frequency;
2892 }
2893
2894 int connman_network_set_wifi_channel(struct connman_network *network,
2895                                                 uint16_t channel)
2896 {
2897         network->wifi.channel = channel;
2898
2899         return 0;
2900 }
2901
2902 int connman_network_set_autoconnect(struct connman_network *network,
2903                                 bool autoconnect)
2904 {
2905         if (!network->driver || !network->driver->set_autoconnect)
2906                 return 0;
2907         return network->driver->set_autoconnect(network, autoconnect);
2908 }
2909
2910 bool __connman_network_native_autoconnect(struct connman_network *network)
2911 {
2912         if (!network->driver || !network->driver->set_autoconnect)
2913                 return false;
2914         return true;
2915 }
2916
2917 uint16_t connman_network_get_wifi_channel(struct connman_network *network)
2918 {
2919         return network->wifi.channel;
2920 }
2921
2922 /**
2923  * connman_network_set_string:
2924  * @network: network structure
2925  * @key: unique identifier
2926  * @value: string value
2927  *
2928  * Set string value for specific key
2929  */
2930 int connman_network_set_string(struct connman_network *network,
2931                                         const char *key, const char *value)
2932 {
2933         if (g_strcmp0(key, "Name") == 0)
2934                 return connman_network_set_name(network, value);
2935
2936         if (g_str_equal(key, "Path")) {
2937                 g_free(network->path);
2938                 network->path = g_strdup(value);
2939         } else if (g_str_equal(key, "Node")) {
2940                 g_free(network->node);
2941                 network->node = g_strdup(value);
2942         } else if (g_str_equal(key, "WiFi.Mode")) {
2943                 g_free(network->wifi.mode);
2944                 network->wifi.mode = g_strdup(value);
2945         } else if (g_str_equal(key, "WiFi.Security")) {
2946                 g_free(network->wifi.security);
2947                 network->wifi.security = g_strdup(value);
2948         } else if (g_str_equal(key, "WiFi.Passphrase")) {
2949 #if defined TIZEN_EXT
2950                 DBG("ConnMan, %p key %s", network, key);
2951 #endif
2952                 g_free(network->wifi.passphrase);
2953                 network->wifi.passphrase = g_strdup(value);
2954         } else if (g_str_equal(key, "WiFi.EAP")) {
2955                 g_free(network->wifi.eap);
2956                 network->wifi.eap = g_strdup(value);
2957         } else if (g_str_equal(key, "WiFi.Identity")) {
2958                 g_free(network->wifi.identity);
2959                 network->wifi.identity = g_strdup(value);
2960         } else if (g_str_equal(key, "WiFi.AnonymousIdentity")) {
2961                 g_free(network->wifi.anonymous_identity);
2962                 network->wifi.anonymous_identity = g_strdup(value);
2963         } else if (g_str_equal(key, "WiFi.AgentIdentity")) {
2964                 g_free(network->wifi.agent_identity);
2965                 network->wifi.agent_identity = g_strdup(value);
2966         } else if (g_str_equal(key, "WiFi.CACertFile")) {
2967                 g_free(network->wifi.ca_cert_path);
2968                 network->wifi.ca_cert_path = g_strdup(value);
2969         } else if (g_str_equal(key, "WiFi.SubjectMatch")) {
2970                 g_free(network->wifi.subject_match);
2971                 network->wifi.subject_match = g_strdup(value);
2972         } else if (g_str_equal(key, "WiFi.AltSubjectMatch")) {
2973                 g_free(network->wifi.altsubject_match);
2974                 network->wifi.altsubject_match = g_strdup(value);
2975         } else if (g_str_equal(key, "WiFi.DomainSuffixMatch")) {
2976                 g_free(network->wifi.domain_suffix_match);
2977                 network->wifi.domain_suffix_match = g_strdup(value);
2978         } else if (g_str_equal(key, "WiFi.DomainMatch")) {
2979                 g_free(network->wifi.domain_match);
2980                 network->wifi.domain_match = g_strdup(value);
2981         } else if (g_str_equal(key, "WiFi.ClientCertFile")) {
2982                 g_free(network->wifi.client_cert_path);
2983                 network->wifi.client_cert_path = g_strdup(value);
2984         } else if (g_str_equal(key, "WiFi.PrivateKeyFile")) {
2985                 g_free(network->wifi.private_key_path);
2986                 network->wifi.private_key_path = g_strdup(value);
2987         } else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase")) {
2988                 g_free(network->wifi.private_key_passphrase);
2989                 network->wifi.private_key_passphrase = g_strdup(value);
2990         } else if (g_str_equal(key, "WiFi.Phase2")) {
2991                 g_free(network->wifi.phase2_auth);
2992                 network->wifi.phase2_auth = g_strdup(value);
2993         } else if (g_str_equal(key, "WiFi.PinWPS")) {
2994                 g_free(network->wifi.pin_wps);
2995                 network->wifi.pin_wps = g_strdup(value);
2996 #if defined TIZEN_EXT
2997         } else if (g_str_equal(key, "WiFi.Connector")) {
2998                 g_free(network->wifi.connector);
2999                 network->wifi.connector = g_strdup(value);
3000         } else if (g_str_equal(key, "WiFi.CSignKey")) {
3001                 g_free(network->wifi.c_sign_key);
3002                 network->wifi.c_sign_key = g_strdup(value);
3003         } else if (g_str_equal(key, "WiFi.NetAccessKey")) {
3004                 g_free(network->wifi.net_access_key);
3005                 network->wifi.net_access_key = g_strdup(value);
3006         } else if (g_str_equal(key, "WiFi.RoamingCurBSSID")) {
3007                 g_free(network->wifi.roaming_cur_bssid);
3008                 network->wifi.roaming_cur_bssid = g_strdup(value);
3009         } else if (g_str_equal(key, "WiFi.RoamingDstBSSID")) {
3010                 g_free(network->wifi.roaming_dst_bssid);
3011                 network->wifi.roaming_dst_bssid = g_strdup(value);
3012 #endif
3013         } else {
3014                 return -EINVAL;
3015         }
3016
3017         return 0;
3018 }
3019
3020 /**
3021  * connman_network_get_string:
3022  * @network: network structure
3023  * @key: unique identifier
3024  *
3025  * Get string value for specific key
3026  */
3027 const char *connman_network_get_string(struct connman_network *network,
3028                                                         const char *key)
3029 {
3030         if (g_str_equal(key, "Path"))
3031                 return network->path;
3032         else if (g_str_equal(key, "Name"))
3033                 return network->name;
3034         else if (g_str_equal(key, "Node"))
3035                 return network->node;
3036         else if (g_str_equal(key, "WiFi.Mode"))
3037                 return network->wifi.mode;
3038         else if (g_str_equal(key, "WiFi.Security"))
3039                 return network->wifi.security;
3040         else if (g_str_equal(key, "WiFi.Passphrase"))
3041                 return network->wifi.passphrase;
3042         else if (g_str_equal(key, "WiFi.EAP"))
3043                 return network->wifi.eap;
3044         else if (g_str_equal(key, "WiFi.Identity"))
3045                 return network->wifi.identity;
3046         else if (g_str_equal(key, "WiFi.AnonymousIdentity"))
3047                 return network->wifi.anonymous_identity;
3048         else if (g_str_equal(key, "WiFi.AgentIdentity"))
3049                 return network->wifi.agent_identity;
3050         else if (g_str_equal(key, "WiFi.CACertFile"))
3051                 return network->wifi.ca_cert_path;
3052         else if (g_str_equal(key, "WiFi.SubjectMatch"))
3053                 return network->wifi.subject_match;
3054         else if (g_str_equal(key, "WiFi.AltSubjectMatch"))
3055                 return network->wifi.altsubject_match;
3056         else if (g_str_equal(key, "WiFi.DomainSuffixMatch"))
3057                 return network->wifi.domain_suffix_match;
3058         else if (g_str_equal(key, "WiFi.DomainMatch"))
3059                 return network->wifi.domain_match;
3060         else if (g_str_equal(key, "WiFi.ClientCertFile"))
3061                 return network->wifi.client_cert_path;
3062         else if (g_str_equal(key, "WiFi.PrivateKeyFile"))
3063                 return network->wifi.private_key_path;
3064         else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase"))
3065                 return network->wifi.private_key_passphrase;
3066         else if (g_str_equal(key, "WiFi.Phase2"))
3067                 return network->wifi.phase2_auth;
3068         else if (g_str_equal(key, "WiFi.PinWPS"))
3069                 return network->wifi.pin_wps;
3070 #if defined TIZEN_EXT
3071         else if (g_str_equal(key, "WiFi.Connector"))
3072                 return network->wifi.connector;
3073         else if (g_str_equal(key, "WiFi.CSignKey"))
3074                 return network->wifi.c_sign_key;
3075         else if (g_str_equal(key, "WiFi.NetAccessKey"))
3076                 return network->wifi.net_access_key;
3077         else if (g_str_equal(key, "WiFi.RoamingCurBSSID"))
3078                 return network->wifi.roaming_cur_bssid;
3079         else if (g_str_equal(key, "WiFi.RoamingDstBSSID"))
3080                 return network->wifi.roaming_dst_bssid;
3081 #endif
3082
3083         return NULL;
3084 }
3085
3086 /**
3087  * connman_network_set_bool:
3088  * @network: network structure
3089  * @key: unique identifier
3090  * @value: boolean value
3091  *
3092  * Set boolean value for specific key
3093  */
3094 int connman_network_set_bool(struct connman_network *network,
3095                                         const char *key, bool value)
3096 {
3097         if (g_strcmp0(key, "Roaming") == 0)
3098                 network->roaming = value;
3099         else if (g_strcmp0(key, "WiFi.WPS") == 0)
3100                 network->wifi.wps = value;
3101         else if (g_strcmp0(key, "WiFi.WPSAdvertising") == 0)
3102                 network->wifi.wps_advertizing = value;
3103         else if (g_strcmp0(key, "WiFi.UseWPS") == 0)
3104                 network->wifi.use_wps = value;
3105 #if defined TIZEN_EXT
3106         else if (g_strcmp0(key, "DefaultInternet") == 0)
3107                 network->default_internet = value;
3108         else if (g_strcmp0(key, "WiFi.HS20AP") == 0)
3109                 network->wifi.isHS20AP = value;
3110         else if (g_strcmp0(key, "WiFi.TRANSITION_MODE") == 0)
3111                 network->wifi.owe_transition_mode = value;
3112         else if (g_strcmp0(key, "WiFi.Roaming") == 0)
3113                 network->wifi.roaming_progress = value;
3114         else if (g_strcmp0(key, "WiFi.RoamingDHCP") == 0)
3115                 network->wifi.roaming_dhcp = value;
3116         else if (g_strcmp0(key, "WiFi.PMFRequired") == 0)
3117                 network->wifi.pmf_required = value;
3118 #endif
3119
3120         return -EINVAL;
3121 }
3122
3123 /**
3124  * connman_network_get_bool:
3125  * @network: network structure
3126  * @key: unique identifier
3127  *
3128  * Get boolean value for specific key
3129  */
3130 bool connman_network_get_bool(struct connman_network *network,
3131                                                         const char *key)
3132 {
3133         if (g_str_equal(key, "Roaming"))
3134                 return network->roaming;
3135         else if (g_str_equal(key, "WiFi.WPS"))
3136                 return network->wifi.wps;
3137         else if (g_str_equal(key, "WiFi.WPSAdvertising"))
3138                 return network->wifi.wps_advertizing;
3139         else if (g_str_equal(key, "WiFi.UseWPS"))
3140                 return network->wifi.use_wps;
3141 #if defined TIZEN_EXT
3142         else if (g_str_equal(key, "DefaultInternet"))
3143                 return network->default_internet;
3144         else if (g_str_equal(key, "WiFi.HS20AP"))
3145                 return network->wifi.isHS20AP;
3146         else if (g_str_equal(key, "WiFi.TRANSITION_MODE"))
3147                 return network->wifi.owe_transition_mode;
3148         else if (g_str_equal(key, "WiFi.Roaming"))
3149                 return network->wifi.roaming_progress;
3150         else if (g_str_equal(key, "WiFi.RoamingDHCP"))
3151                 return network->wifi.roaming_dhcp;
3152         else if (g_str_equal(key, "WiFi.PMFRequired"))
3153                 return network->wifi.pmf_required;
3154 #endif
3155
3156         return false;
3157 }
3158
3159 #if defined TIZEN_EXT
3160 /**
3161  * connman_network_set_vsie_list:
3162  * @network: network structure
3163  * @vsie_list: GSList pointer
3164  *
3165  * Set vendor specific list pointer
3166  */
3167 void connman_network_set_vsie_list(struct connman_network *network, GSList *vsie_list)
3168 {
3169         g_slist_free_full(network->wifi.vsie_list, g_free);
3170         network->wifi.vsie_list = vsie_list;
3171 }
3172
3173 /**
3174  * connman_network_get_vsie_list:
3175  * @network: network structure
3176  *
3177  * Get vendor specific list pointer
3178  */
3179 void *connman_network_get_vsie_list(struct connman_network *network)
3180 {
3181         return network->wifi.vsie_list;
3182 }
3183 #endif
3184
3185 /**
3186  * connman_network_set_blob:
3187  * @network: network structure
3188  * @key: unique identifier
3189  * @data: blob data
3190  * @size: blob size
3191  *
3192  * Set binary blob value for specific key
3193  */
3194 int connman_network_set_blob(struct connman_network *network,
3195                         const char *key, const void *data, unsigned int size)
3196 {
3197         if (g_str_equal(key, "WiFi.SSID")) {
3198                 g_free(network->wifi.ssid);
3199                 network->wifi.ssid = g_try_malloc(size);
3200                 if (network->wifi.ssid) {
3201                         memcpy(network->wifi.ssid, data, size);
3202                         network->wifi.ssid_len = size;
3203                 } else
3204                         network->wifi.ssid_len = 0;
3205 #ifdef TIZEN_EXT
3206         } else if (g_str_equal(key, "WiFi.TRANSITION_MODE_SSID")) {
3207                 g_free(network->wifi.transition_mode_ssid);
3208                 network->wifi.transition_mode_ssid = g_try_malloc(size);
3209                 if (network->wifi.transition_mode_ssid) {
3210                         memcpy(network->wifi.transition_mode_ssid, data, size);
3211                         network->wifi.transition_mode_ssid_len = size;
3212                 } else
3213                         network->wifi.transition_mode_ssid_len = 0;
3214 #endif
3215         } else {
3216                 return -EINVAL;
3217         }
3218
3219         return 0;
3220 }
3221
3222 /**
3223  * connman_network_get_blob:
3224  * @network: network structure
3225  * @key: unique identifier
3226  * @size: pointer to blob size
3227  *
3228  * Get binary blob value for specific key
3229  */
3230 const void *connman_network_get_blob(struct connman_network *network,
3231                                         const char *key, unsigned int *size)
3232 {
3233         if (g_str_equal(key, "WiFi.SSID")) {
3234                 if (size)
3235                         *size = network->wifi.ssid_len;
3236                 return network->wifi.ssid;
3237 #ifdef TIZEN_EXT
3238         } else if (g_str_equal(key, "WiFi.TRANSITION_MODE_SSID")) {
3239                 if (size)
3240                         *size = network->wifi.transition_mode_ssid_len;
3241                 return network->wifi.transition_mode_ssid;
3242 #endif
3243         }
3244
3245         return NULL;
3246 }
3247
3248 void __connman_network_set_device(struct connman_network *network,
3249                                         struct connman_device *device)
3250 {
3251         if (network->device == device)
3252                 return;
3253
3254         if (network->device)
3255                 network_remove(network);
3256
3257         network->device = device;
3258
3259         if (network->device)
3260                 network_probe(network);
3261 }
3262
3263 /**
3264  * connman_network_get_device:
3265  * @network: network structure
3266  *
3267  * Get parent device of network
3268  */
3269 struct connman_device *connman_network_get_device(struct connman_network *network)
3270 {
3271         return network->device;
3272 }
3273
3274 /**
3275  * connman_network_get_data:
3276  * @network: network structure
3277  *
3278  * Get private network data pointer
3279  */
3280 void *connman_network_get_data(struct connman_network *network)
3281 {
3282         return network->driver_data;
3283 }
3284
3285 /**
3286  * connman_network_set_data:
3287  * @network: network structure
3288  * @data: data pointer
3289  *
3290  * Set private network data pointer
3291  */
3292 void connman_network_set_data(struct connman_network *network, void *data)
3293 {
3294         network->driver_data = data;
3295 }
3296
3297 void connman_network_update(struct connman_network *network)
3298 {
3299         switch (network->type) {
3300         case CONNMAN_NETWORK_TYPE_UNKNOWN:
3301         case CONNMAN_NETWORK_TYPE_VENDOR:
3302                 return;
3303         case CONNMAN_NETWORK_TYPE_ETHERNET:
3304         case CONNMAN_NETWORK_TYPE_GADGET:
3305         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
3306         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
3307         case CONNMAN_NETWORK_TYPE_CELLULAR:
3308         case CONNMAN_NETWORK_TYPE_WIFI:
3309                 break;
3310         }
3311
3312         if (network->group)
3313                 __connman_service_update_from_network(network);
3314 }
3315
3316 int __connman_network_init(void)
3317 {
3318         DBG("");
3319 #if defined TIZEN_EXT
3320         connection = connman_dbus_get_connection();
3321 #endif
3322
3323         return 0;
3324 }
3325
3326 void __connman_network_cleanup(void)
3327 {
3328         DBG("");
3329 #if defined TIZEN_EXT
3330         dbus_connection_unref(connection);
3331 #endif
3332 }