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