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