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