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