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