Merge "In dhcpv6 request always set G_DHCPV6_IA_NA option." into tizen
[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
31 /*
32  * How many times to send RS with the purpose of
33  * refreshing RDNSS entries before they actually expire.
34  * With a value of 1, one RS will be sent, with no retries.
35  */
36 #define RS_REFRESH_COUNT        1
37
38 /*
39  * Value in seconds to wait for RA after RS was sent.
40  * After this time elapsed, we can send another RS.
41  */
42 #define RS_REFRESH_TIMEOUT      3
43
44 #if defined TIZEN_EXT
45 #define WIFI_ENCYPTION_MODE_LEN_MAX 6
46 #define WIFI_BSSID_LEN_MAX 6
47 #endif
48
49 static GSList *network_list = NULL;
50 static GSList *driver_list = NULL;
51
52 struct connman_network {
53         int refcount;
54         enum connman_network_type type;
55         bool available;
56         bool connected;
57         bool roaming;
58         uint8_t strength;
59         uint16_t frequency;
60         char *identifier;
61         char *name;
62         char *node;
63         char *group;
64         char *path;
65         int index;
66         int router_solicit_count;
67         int router_solicit_refresh_count;
68
69         struct connman_network_driver *driver;
70         void *driver_data;
71
72         bool connecting;
73         bool associating;
74
75         struct connman_device *device;
76
77         struct {
78                 void *ssid;
79                 int ssid_len;
80                 char *mode;
81                 unsigned short channel;
82                 char *security;
83                 char *passphrase;
84                 char *eap;
85                 char *identity;
86                 char *agent_identity;
87                 char *ca_cert_path;
88                 char *client_cert_path;
89                 char *private_key_path;
90                 char *private_key_passphrase;
91                 char *phase2_auth;
92                 bool wps;
93                 bool use_wps;
94                 char *pin_wps;
95 #if defined TIZEN_EXT
96                 char encryption_mode[WIFI_ENCYPTION_MODE_LEN_MAX];
97                 unsigned char bssid[WIFI_BSSID_LEN_MAX];
98                 unsigned int maxrate;
99                 unsigned int isHS20AP;
100                 unsigned int keymgmt;
101                 char *keymgmt_type;
102                 bool rsn_mode;
103                 int disconnect_reason;
104                 int assoc_status_code;
105                 void *wifi_vsie;
106                 unsigned int wifi_vsie_len;
107 #endif
108         } wifi;
109
110 #if defined TIZEN_EXT
111         /* Multiple APN services and a default APN which a user selected */
112         bool default_internet;
113 #endif
114
115 };
116
117 static const char *type2string(enum connman_network_type type)
118 {
119         switch (type) {
120         case CONNMAN_NETWORK_TYPE_UNKNOWN:
121         case CONNMAN_NETWORK_TYPE_VENDOR:
122                 break;
123         case CONNMAN_NETWORK_TYPE_ETHERNET:
124                 return "ethernet";
125         case CONNMAN_NETWORK_TYPE_GADGET:
126                 return "gadget";
127         case CONNMAN_NETWORK_TYPE_WIFI:
128                 return "wifi";
129         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
130         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
131                 return "bluetooth";
132         case CONNMAN_NETWORK_TYPE_CELLULAR:
133                 return "cellular";
134         }
135
136         return NULL;
137 }
138
139 static bool match_driver(struct connman_network *network,
140                                         struct connman_network_driver *driver)
141 {
142         if (network->type == driver->type ||
143                         driver->type == CONNMAN_NETWORK_TYPE_UNKNOWN)
144                 return true;
145
146         return false;
147 }
148
149 static void set_configuration(struct connman_network *network,
150                         enum connman_ipconfig_type type)
151 {
152         struct connman_service *service;
153
154         DBG("network %p", network);
155
156         if (!network->device)
157                 return;
158
159         __connman_device_set_network(network->device, network);
160
161         connman_device_set_disconnected(network->device, false);
162
163         service = connman_service_lookup_from_network(network);
164         __connman_service_ipconfig_indicate_state(service,
165                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
166                                         type);
167 }
168
169 static void dhcp_success(struct connman_network *network)
170 {
171         struct connman_service *service;
172         struct connman_ipconfig *ipconfig_ipv4;
173         int err;
174
175         service = connman_service_lookup_from_network(network);
176         if (!service)
177                 goto err;
178
179         ipconfig_ipv4 = __connman_service_get_ip4config(service);
180
181         DBG("lease acquired for ipconfig %p", ipconfig_ipv4);
182
183         if (!ipconfig_ipv4)
184                 return;
185
186         err = __connman_ipconfig_address_add(ipconfig_ipv4);
187         if (err < 0)
188                 goto err;
189
190 #if defined TIZEN_EXT
191         err = __connman_ipconfig_gateway_add(ipconfig_ipv4, service);
192 #else
193         err = __connman_ipconfig_gateway_add(ipconfig_ipv4);
194 #endif
195         if (err < 0)
196                 goto err;
197
198         return;
199
200 err:
201         connman_network_set_error(network,
202                                 CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
203 }
204
205 static void dhcp_failure(struct connman_network *network)
206 {
207         struct connman_service *service;
208         struct connman_ipconfig *ipconfig_ipv4;
209
210         service = connman_service_lookup_from_network(network);
211         if (!service)
212                 return;
213
214         ipconfig_ipv4 = __connman_service_get_ip4config(service);
215
216         DBG("lease lost for ipconfig %p", ipconfig_ipv4);
217
218         if (!ipconfig_ipv4)
219                 return;
220
221         __connman_ipconfig_address_remove(ipconfig_ipv4);
222         __connman_ipconfig_gateway_remove(ipconfig_ipv4);
223 }
224
225 static void dhcp_callback(struct connman_ipconfig *ipconfig,
226                         struct connman_network *network,
227                         bool success, gpointer data)
228 {
229         network->connecting = false;
230
231         if (success)
232                 dhcp_success(network);
233         else
234                 dhcp_failure(network);
235 }
236
237 static int set_connected_manual(struct connman_network *network)
238 {
239         int err = 0;
240         struct connman_service *service;
241         struct connman_ipconfig *ipconfig;
242
243         DBG("network %p", network);
244
245         network->connecting = false;
246
247         service = connman_service_lookup_from_network(network);
248
249         ipconfig = __connman_service_get_ip4config(service);
250
251         if (!__connman_ipconfig_get_local(ipconfig))
252                 __connman_service_read_ip4config(service);
253
254         err = __connman_ipconfig_address_add(ipconfig);
255         if (err < 0)
256                 goto err;
257
258 #if defined TIZEN_EXT
259         err = __connman_ipconfig_gateway_add(ipconfig, service);
260 #else
261         err = __connman_ipconfig_gateway_add(ipconfig);
262 #endif
263         if (err < 0)
264                 goto err;
265
266 err:
267         return err;
268 }
269
270 static int set_connected_dhcp(struct connman_network *network)
271 {
272         struct connman_service *service;
273         struct connman_ipconfig *ipconfig_ipv4;
274         int err;
275
276         DBG("network %p", network);
277
278         service = connman_service_lookup_from_network(network);
279         ipconfig_ipv4 = __connman_service_get_ip4config(service);
280
281         err = __connman_dhcp_start(ipconfig_ipv4, network,
282                                                         dhcp_callback, NULL);
283         if (err < 0) {
284                 connman_error("Can not request DHCP lease");
285                 return err;
286         }
287
288         return 0;
289 }
290
291 static int manual_ipv6_set(struct connman_network *network,
292                                 struct connman_ipconfig *ipconfig_ipv6)
293 {
294         struct connman_service *service;
295         int err;
296
297         DBG("network %p ipv6 %p", network, ipconfig_ipv6);
298
299         service = connman_service_lookup_from_network(network);
300         if (!service)
301                 return -EINVAL;
302
303         if (!__connman_ipconfig_get_local(ipconfig_ipv6))
304                 __connman_service_read_ip6config(service);
305
306         __connman_ipconfig_enable_ipv6(ipconfig_ipv6);
307
308         err = __connman_ipconfig_address_add(ipconfig_ipv6);
309         if (err < 0) {
310                 connman_network_set_error(network,
311                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
312                 return err;
313         }
314
315 #if defined TIZEN_EXT
316         err = __connman_ipconfig_gateway_add(ipconfig_ipv6, service);
317 #else
318         err = __connman_ipconfig_gateway_add(ipconfig_ipv6);
319 #endif
320         if (err < 0)
321                 return err;
322
323         __connman_connection_gateway_activate(service,
324                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
325
326         __connman_device_set_network(network->device, network);
327
328         connman_device_set_disconnected(network->device, false);
329
330         connman_network_set_associating(network, false);
331
332         network->connecting = false;
333
334         return 0;
335 }
336
337 static void stop_dhcpv6(struct connman_network *network)
338 {
339         network->connecting = false;
340
341         __connman_dhcpv6_stop(network);
342 }
343
344 static void dhcpv6_release_callback(struct connman_network *network,
345                                 enum __connman_dhcpv6_status status,
346                                 gpointer data)
347 {
348         DBG("status %d", status);
349
350         stop_dhcpv6(network);
351 }
352
353 static void release_dhcpv6(struct connman_network *network)
354 {
355         __connman_dhcpv6_start_release(network, dhcpv6_release_callback);
356         stop_dhcpv6(network);
357 }
358
359 static void dhcpv6_info_callback(struct connman_network *network,
360                                 enum __connman_dhcpv6_status status,
361                                 gpointer data)
362 {
363         DBG("status %d", status);
364
365         stop_dhcpv6(network);
366 }
367
368 static int dhcpv6_set_addresses(struct connman_network *network)
369 {
370         struct connman_service *service;
371         struct connman_ipconfig *ipconfig_ipv6;
372         int err = -EINVAL;
373
374         service = connman_service_lookup_from_network(network);
375         if (!service)
376                 goto err;
377
378         network->connecting = false;
379
380         ipconfig_ipv6 = __connman_service_get_ip6config(service);
381         err = __connman_ipconfig_address_add(ipconfig_ipv6);
382         if (err < 0)
383                 goto err;
384
385         return 0;
386
387 err:
388         connman_network_set_error(network,
389                                 CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
390         return err;
391 }
392
393 static void autoconf_ipv6_set(struct connman_network *network);
394 static void dhcpv6_callback(struct connman_network *network,
395                         enum __connman_dhcpv6_status status, gpointer data);
396
397 /*
398  * Have a separate callback for renew so that we do not do autoconf
399  * in wrong phase as the dhcpv6_callback() is also called when doing
400  * DHCPv6 solicitation.
401  */
402 static void dhcpv6_renew_callback(struct connman_network *network,
403                                 enum __connman_dhcpv6_status status,
404                                 gpointer data)
405 {
406         switch (status) {
407         case CONNMAN_DHCPV6_STATUS_SUCCEED:
408                 dhcpv6_callback(network, status, data);
409                 break;
410         case CONNMAN_DHCPV6_STATUS_FAIL:
411         case CONNMAN_DHCPV6_STATUS_RESTART:
412                 stop_dhcpv6(network);
413
414                 /* restart and do solicit again. */
415                 autoconf_ipv6_set(network);
416                 break;
417         }
418 }
419
420 static void dhcpv6_callback(struct connman_network *network,
421                         enum __connman_dhcpv6_status status, gpointer data)
422 {
423         DBG("status %d", status);
424
425         /* Start the renew process if necessary */
426         if (status == CONNMAN_DHCPV6_STATUS_SUCCEED) {
427
428                 if (dhcpv6_set_addresses(network) < 0) {
429                         stop_dhcpv6(network);
430                         return;
431                 }
432
433                 if (__connman_dhcpv6_start_renew(network,
434                                         dhcpv6_renew_callback) == -ETIMEDOUT)
435                         dhcpv6_renew_callback(network,
436                                                 CONNMAN_DHCPV6_STATUS_FAIL,
437                                                 data);
438
439         } else if (status == CONNMAN_DHCPV6_STATUS_RESTART) {
440                 stop_dhcpv6(network);
441                 autoconf_ipv6_set(network);
442         } else
443                 stop_dhcpv6(network);
444 }
445
446 static void check_dhcpv6(struct nd_router_advert *reply,
447                         unsigned int length, void *user_data)
448 {
449         struct connman_network *network = user_data;
450         struct connman_service *service;
451         GSList *prefixes;
452
453         DBG("reply %p", reply);
454
455         if (!reply) {
456                 /*
457                  * Router solicitation message seem to get lost easily so
458                  * try to send it again.
459                  */
460                 if (network->router_solicit_count > 0) {
461                         DBG("re-send router solicitation %d",
462                                                 network->router_solicit_count);
463                         network->router_solicit_count--;
464                         __connman_inet_ipv6_send_rs(network->index, 1,
465                                                 check_dhcpv6, network);
466                         return;
467                 }
468 #if defined TIZEN_EXT
469                 DBG("RA message is not received from server in reply of RS.");
470 #endif
471                 connman_network_unref(network);
472                 return;
473         }
474
475         network->router_solicit_count = 0;
476
477         /*
478          * If we were disconnected while waiting router advertisement,
479          * we just quit and do not start DHCPv6
480          */
481         if (!network->connected) {
482                 connman_network_unref(network);
483 #if defined TIZEN_EXT
484                 DBG("Network is not connected");
485 #endif
486                 return;
487         }
488
489         prefixes = __connman_inet_ipv6_get_prefixes(reply, length);
490
491         /*
492          * If IPv6 config is missing from service, then create it.
493          * The ipconfig might be missing if we got a rtnl message
494          * that disabled IPv6 config and thus removed it. This
495          * can happen if we are switching from one service to
496          * another in the same interface. The only way to get IPv6
497          * config back is to re-create it here.
498          */
499         service = connman_service_lookup_from_network(network);
500         if (service) {
501                 connman_service_create_ip6config(service, network->index);
502
503                 connman_network_set_associating(network, false);
504
505                 __connman_service_ipconfig_indicate_state(service,
506                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
507                                         CONNMAN_IPCONFIG_TYPE_IPV6);
508         }
509
510         /*
511          * We do stateful/stateless DHCPv6 if router advertisement says so.
512          */
513         if (reply->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) {
514 #if defined TIZEN_EXT
515                 DBG("IPv6 ND_RA_FLAG_MANAGED");
516 #endif
517                 __connman_dhcpv6_start(network, prefixes, dhcpv6_callback);
518         } else {
519                 if (reply->nd_ra_flags_reserved & ND_RA_FLAG_OTHER)
520 #if defined TIZEN_EXT
521                 {
522                         DBG("IPv6 ND_RA_FLAG_OTHER");
523 #endif
524                         __connman_dhcpv6_start_info(network,
525                                                         dhcpv6_info_callback);
526 #if defined TIZEN_EXT
527                 }
528 #endif
529
530                 g_slist_free_full(prefixes, g_free);
531                 network->connecting = false;
532         }
533
534         connman_network_unref(network);
535 }
536
537 static void receive_refresh_rs_reply(struct nd_router_advert *reply,
538                 unsigned int length, void *user_data)
539 {
540         struct connman_network *network = user_data;
541
542         DBG("reply %p", reply);
543
544         if (!reply) {
545                 /*
546                  * Router solicitation message seem to get lost easily so
547                  * try to send it again.
548                  */
549                 if (network->router_solicit_refresh_count > 1) {
550                         network->router_solicit_refresh_count--;
551                         DBG("re-send router solicitation %d",
552                                         network->router_solicit_refresh_count);
553                         __connman_inet_ipv6_send_rs(network->index,
554                                         RS_REFRESH_TIMEOUT,
555                                         receive_refresh_rs_reply,
556                                         network);
557                         return;
558                 }
559         }
560
561         /* RS refresh not in progress anymore */
562         network->router_solicit_refresh_count = 0;
563
564         connman_network_unref(network);
565         return;
566 }
567
568 int __connman_network_refresh_rs_ipv6(struct connman_network *network,
569                                         int index)
570 {
571         int ret = 0;
572
573         DBG("network %p index %d", network, index);
574
575         /* Send only one RS for all RDNSS entries which are about to expire */
576         if (network->router_solicit_refresh_count > 0) {
577                 DBG("RS refresh already started");
578                 return 0;
579         }
580
581         network->router_solicit_refresh_count = RS_REFRESH_COUNT;
582
583         connman_network_ref(network);
584
585         ret = __connman_inet_ipv6_send_rs(index, RS_REFRESH_TIMEOUT,
586                         receive_refresh_rs_reply, network);
587         return ret;
588 }
589
590 static void autoconf_ipv6_set(struct connman_network *network)
591 {
592         struct connman_service *service;
593         struct connman_ipconfig *ipconfig;
594         int index;
595
596         DBG("network %p", network);
597
598         if (network->router_solicit_count > 0) {
599                 /*
600                  * The autoconfiguration is already pending and we have sent
601                  * router solicitation messages and are now waiting answers.
602                  * There is no need to continue any further.
603                  */
604                 DBG("autoconfiguration already started");
605                 return;
606         }
607
608         __connman_device_set_network(network->device, network);
609
610         connman_device_set_disconnected(network->device, false);
611
612 #if defined TIZEN_EXT
613         if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR)
614                 return;
615 #endif
616
617         service = connman_service_lookup_from_network(network);
618         if (!service)
619                 return;
620
621         ipconfig = __connman_service_get_ip6config(service);
622         if (!ipconfig)
623                 return;
624
625         __connman_ipconfig_enable_ipv6(ipconfig);
626
627         __connman_ipconfig_address_remove(ipconfig);
628
629         index = __connman_ipconfig_get_index(ipconfig);
630
631         connman_network_ref(network);
632
633         /* Try to get stateless DHCPv6 information, RFC 3736 */
634         network->router_solicit_count = 3;
635         __connman_inet_ipv6_send_rs(index, 1, check_dhcpv6, network);
636 }
637
638 static void set_connected(struct connman_network *network)
639 {
640         struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
641         struct connman_service *service;
642
643         if (network->connected)
644                 return;
645
646         connman_network_set_associating(network, false);
647
648         network->connected = true;
649
650         service = connman_service_lookup_from_network(network);
651
652         ipconfig_ipv4 = __connman_service_get_ip4config(service);
653         ipconfig_ipv6 = __connman_service_get_ip6config(service);
654
655         DBG("service %p ipv4 %p ipv6 %p", service, ipconfig_ipv4,
656                 ipconfig_ipv6);
657
658         __connman_network_enable_ipconfig(network, ipconfig_ipv4);
659         __connman_network_enable_ipconfig(network, ipconfig_ipv6);
660 }
661
662 static void set_disconnected(struct connman_network *network)
663 {
664         struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
665         enum connman_ipconfig_method ipv4_method, ipv6_method;
666         enum connman_service_state state;
667         struct connman_service *service;
668
669         service = connman_service_lookup_from_network(network);
670
671         ipconfig_ipv4 = __connman_service_get_ip4config(service);
672         ipconfig_ipv6 = __connman_service_get_ip6config(service);
673
674         DBG("service %p ipv4 %p ipv6 %p", service, ipconfig_ipv4,
675                 ipconfig_ipv6);
676
677         ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4);
678         ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6);
679
680         DBG("method ipv4 %d ipv6 %d", ipv4_method, ipv6_method);
681
682         /*
683          * Resetting solicit count here will prevent the RS resend loop
684          * from sending packets in check_dhcpv6()
685          */
686         network->router_solicit_count = 0;
687
688         __connman_device_set_network(network->device, NULL);
689
690         if (network->connected) {
691                 switch (ipv6_method) {
692                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
693                 case CONNMAN_IPCONFIG_METHOD_OFF:
694                 case CONNMAN_IPCONFIG_METHOD_FIXED:
695                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
696                         break;
697                 case CONNMAN_IPCONFIG_METHOD_DHCP:
698                 case CONNMAN_IPCONFIG_METHOD_AUTO:
699                         release_dhcpv6(network);
700                         break;
701                 }
702
703                 switch (ipv4_method) {
704                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
705                 case CONNMAN_IPCONFIG_METHOD_OFF:
706                 case CONNMAN_IPCONFIG_METHOD_AUTO:
707                 case CONNMAN_IPCONFIG_METHOD_FIXED:
708                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
709                         break;
710                 case CONNMAN_IPCONFIG_METHOD_DHCP:
711                         __connman_dhcp_stop(ipconfig_ipv4);
712                         break;
713                 }
714         }
715
716         /*
717          * We only set the disconnect state if we were not in idle
718          * or in failure. It does not make sense to go to disconnect
719          * state if we were not connected.
720          */
721         state = __connman_service_ipconfig_get_state(service,
722                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
723         if (state != CONNMAN_SERVICE_STATE_IDLE &&
724                         state != CONNMAN_SERVICE_STATE_FAILURE)
725                 __connman_service_ipconfig_indicate_state(service,
726                                         CONNMAN_SERVICE_STATE_DISCONNECT,
727                                         CONNMAN_IPCONFIG_TYPE_IPV4);
728
729         state = __connman_service_ipconfig_get_state(service,
730                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
731         if (state != CONNMAN_SERVICE_STATE_IDLE &&
732                                 state != CONNMAN_SERVICE_STATE_FAILURE)
733                 __connman_service_ipconfig_indicate_state(service,
734                                         CONNMAN_SERVICE_STATE_DISCONNECT,
735                                         CONNMAN_IPCONFIG_TYPE_IPV6);
736
737         if (network->connected) {
738 #if defined TIZEN_EXT
739                 /**
740                  * Do not remove gateway and its address,
741                  * if there are connected profiles that use same interface (multiple PDN)
742                  */
743                 if (connman_service_get_type(service) != CONNMAN_SERVICE_TYPE_CELLULAR ||
744                                 __connman_service_get_connected_count_of_iface(service) <= 0) {
745 #endif
746                 __connman_connection_gateway_remove(service,
747                                                 CONNMAN_IPCONFIG_TYPE_ALL);
748
749                 __connman_ipconfig_address_unset(ipconfig_ipv4);
750                 __connman_ipconfig_address_unset(ipconfig_ipv6);
751 #if defined TIZEN_EXT
752                 }
753 #endif
754                 /*
755                  * Special handling for IPv6 autoconfigured address.
756                  * The simplest way to remove autoconfigured routes is to
757                  * disable IPv6 temporarily so that kernel will do the cleanup
758                  * automagically.
759                  */
760                 if (ipv6_method == CONNMAN_IPCONFIG_METHOD_AUTO) {
761                         __connman_ipconfig_disable_ipv6(ipconfig_ipv6);
762                         __connman_ipconfig_enable_ipv6(ipconfig_ipv6);
763                 }
764         }
765
766         __connman_service_ipconfig_indicate_state(service,
767                                                 CONNMAN_SERVICE_STATE_IDLE,
768                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
769
770         __connman_service_ipconfig_indicate_state(service,
771                                                 CONNMAN_SERVICE_STATE_IDLE,
772                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
773
774         network->connecting = false;
775         network->connected = false;
776
777         connman_network_set_associating(network, false);
778 }
779
780
781
782 static int network_probe(struct connman_network *network)
783 {
784         GSList *list;
785         struct connman_network_driver *driver = NULL;
786
787         DBG("network %p name %s", network, network->name);
788
789         if (network->driver)
790                 return -EALREADY;
791
792         for (list = driver_list; list; list = list->next) {
793                 driver = list->data;
794
795                 if (!match_driver(network, driver)) {
796                         driver = NULL;
797                         continue;
798                 }
799
800                 DBG("driver %p name %s", driver, driver->name);
801
802                 if (driver->probe(network) == 0)
803                         break;
804
805                 driver = NULL;
806         }
807
808         if (!driver)
809                 return -ENODEV;
810
811         if (!network->group)
812                 return -EINVAL;
813
814         switch (network->type) {
815         case CONNMAN_NETWORK_TYPE_UNKNOWN:
816         case CONNMAN_NETWORK_TYPE_VENDOR:
817                 return 0;
818         case CONNMAN_NETWORK_TYPE_ETHERNET:
819         case CONNMAN_NETWORK_TYPE_GADGET:
820         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
821         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
822         case CONNMAN_NETWORK_TYPE_CELLULAR:
823         case CONNMAN_NETWORK_TYPE_WIFI:
824                 network->driver = driver;
825                 if (!__connman_service_create_from_network(network)) {
826                         network->driver = NULL;
827                         return -EINVAL;
828                 }
829         }
830
831         return 0;
832 }
833
834 static void network_remove(struct connman_network *network)
835 {
836         DBG("network %p name %s", network, network->name);
837
838         if (!network->driver)
839                 return;
840
841         if (network->connected)
842                 set_disconnected(network);
843
844         switch (network->type) {
845         case CONNMAN_NETWORK_TYPE_UNKNOWN:
846         case CONNMAN_NETWORK_TYPE_VENDOR:
847                 break;
848         case CONNMAN_NETWORK_TYPE_ETHERNET:
849         case CONNMAN_NETWORK_TYPE_GADGET:
850         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
851         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
852         case CONNMAN_NETWORK_TYPE_CELLULAR:
853         case CONNMAN_NETWORK_TYPE_WIFI:
854                 if (network->group) {
855                         __connman_service_remove_from_network(network);
856
857                         g_free(network->group);
858                         network->group = NULL;
859                 }
860                 break;
861         }
862
863         if (network->driver->remove)
864                 network->driver->remove(network);
865
866         network->driver = NULL;
867 }
868
869 static void probe_driver(struct connman_network_driver *driver)
870 {
871         GSList *list;
872
873         DBG("driver %p name %s", driver, driver->name);
874
875         for (list = network_list; list; list = list->next) {
876                 struct connman_network *network = list->data;
877
878                 if (network->driver)
879                         continue;
880
881                 if (driver->type != network->type)
882                         continue;
883
884                 if (driver->probe(network) < 0)
885                         continue;
886
887                 network->driver = driver;
888         }
889 }
890
891 static void remove_driver(struct connman_network_driver *driver)
892 {
893         GSList *list;
894
895         DBG("driver %p name %s", driver, driver->name);
896
897         for (list = network_list; list; list = list->next) {
898                 struct connman_network *network = list->data;
899
900                 if (network->driver == driver)
901                         network_remove(network);
902         }
903 }
904
905 static gint compare_priority(gconstpointer a, gconstpointer b)
906 {
907         const struct connman_network_driver *driver1 = a;
908         const struct connman_network_driver *driver2 = b;
909
910         return driver2->priority - driver1->priority;
911 }
912
913 /**
914  * connman_network_driver_register:
915  * @driver: network driver definition
916  *
917  * Register a new network driver
918  *
919  * Returns: %0 on success
920  */
921 int connman_network_driver_register(struct connman_network_driver *driver)
922 {
923         DBG("driver %p name %s", driver, driver->name);
924
925         driver_list = g_slist_insert_sorted(driver_list, driver,
926                                                         compare_priority);
927
928         probe_driver(driver);
929
930         return 0;
931 }
932
933 /**
934  * connman_network_driver_unregister:
935  * @driver: network driver definition
936  *
937  * Remove a previously registered network driver
938  */
939 void connman_network_driver_unregister(struct connman_network_driver *driver)
940 {
941         DBG("driver %p name %s", driver, driver->name);
942
943         driver_list = g_slist_remove(driver_list, driver);
944
945         remove_driver(driver);
946 }
947
948 static void network_destruct(struct connman_network *network)
949 {
950         DBG("network %p name %s", network, network->name);
951
952         g_free(network->wifi.ssid);
953         g_free(network->wifi.mode);
954         g_free(network->wifi.security);
955         g_free(network->wifi.passphrase);
956         g_free(network->wifi.eap);
957         g_free(network->wifi.identity);
958         g_free(network->wifi.agent_identity);
959         g_free(network->wifi.ca_cert_path);
960         g_free(network->wifi.client_cert_path);
961         g_free(network->wifi.private_key_path);
962         g_free(network->wifi.private_key_passphrase);
963         g_free(network->wifi.phase2_auth);
964         g_free(network->wifi.pin_wps);
965 #if defined TIZEN_EXT
966         g_free(network->wifi.wifi_vsie);
967 #endif
968         g_free(network->path);
969         g_free(network->group);
970         g_free(network->node);
971         g_free(network->name);
972         g_free(network->identifier);
973
974         network->device = NULL;
975
976         g_free(network);
977 }
978
979 /**
980  * connman_network_create:
981  * @identifier: network identifier (for example an unqiue name)
982  *
983  * Allocate a new network and assign the #identifier to it.
984  *
985  * Returns: a newly-allocated #connman_network structure
986  */
987 struct connman_network *connman_network_create(const char *identifier,
988                                                 enum connman_network_type type)
989 {
990         struct connman_network *network;
991         char *ident;
992
993         DBG("identifier %s type %d", identifier, type);
994
995         network = g_try_new0(struct connman_network, 1);
996         if (!network)
997                 return NULL;
998
999         DBG("network %p", network);
1000
1001         network->refcount = 1;
1002
1003         ident = g_strdup(identifier);
1004
1005         if (!ident) {
1006                 g_free(network);
1007                 return NULL;
1008         }
1009
1010         network->type       = type;
1011         network->identifier = ident;
1012
1013         network_list = g_slist_prepend(network_list, network);
1014
1015         return network;
1016 }
1017
1018 /**
1019  * connman_network_ref:
1020  * @network: network structure
1021  *
1022  * Increase reference counter of  network
1023  */
1024 struct connman_network *
1025 connman_network_ref_debug(struct connman_network *network,
1026                         const char *file, int line, const char *caller)
1027 {
1028         DBG("%p name %s ref %d by %s:%d:%s()", network, network->name,
1029                 network->refcount + 1, file, line, caller);
1030
1031         __sync_fetch_and_add(&network->refcount, 1);
1032
1033         return network;
1034 }
1035
1036 /**
1037  * connman_network_unref:
1038  * @network: network structure
1039  *
1040  * Decrease reference counter of network
1041  */
1042 void connman_network_unref_debug(struct connman_network *network,
1043                                 const char *file, int line, const char *caller)
1044 {
1045         DBG("%p name %s ref %d by %s:%d:%s()", network, network->name,
1046                 network->refcount - 1, file, line, caller);
1047
1048         if (__sync_fetch_and_sub(&network->refcount, 1) != 1)
1049                 return;
1050
1051         network_list = g_slist_remove(network_list, network);
1052
1053         network_destruct(network);
1054 }
1055
1056 const char *__connman_network_get_type(struct connman_network *network)
1057 {
1058         return type2string(network->type);
1059 }
1060
1061 /**
1062  * connman_network_get_type:
1063  * @network: network structure
1064  *
1065  * Get type of network
1066  */
1067 enum connman_network_type connman_network_get_type(
1068                                 struct connman_network *network)
1069 {
1070         return network->type;
1071 }
1072
1073 /**
1074  * connman_network_get_identifier:
1075  * @network: network structure
1076  *
1077  * Get identifier of network
1078  */
1079 const char *connman_network_get_identifier(struct connman_network *network)
1080 {
1081         return network->identifier;
1082 }
1083
1084 /**
1085  * connman_network_set_index:
1086  * @network: network structure
1087  * @index: index number
1088  *
1089  * Set index number of network
1090  */
1091 void connman_network_set_index(struct connman_network *network, int index)
1092 {
1093         struct connman_service *service;
1094         struct connman_ipconfig *ipconfig;
1095
1096         service = connman_service_lookup_from_network(network);
1097         if (!service)
1098                 goto done;
1099
1100         ipconfig = __connman_service_get_ip4config(service);
1101         if (ipconfig) {
1102                 __connman_ipconfig_set_index(ipconfig, index);
1103
1104                 DBG("index %d service %p ip4config %p", network->index,
1105                         service, ipconfig);
1106         }
1107
1108         ipconfig = __connman_service_get_ip6config(service);
1109         if (ipconfig) {
1110                 __connman_ipconfig_set_index(ipconfig, index);
1111
1112                 DBG("index %d service %p ip6config %p", network->index,
1113                         service, ipconfig);
1114         }
1115
1116 done:
1117         network->index = index;
1118 }
1119
1120 /**
1121  * connman_network_get_index:
1122  * @network: network structure
1123  *
1124  * Get index number of network
1125  */
1126 int connman_network_get_index(struct connman_network *network)
1127 {
1128         return network->index;
1129 }
1130
1131 /**
1132  * connman_network_set_group:
1133  * @network: network structure
1134  * @group: group name
1135  *
1136  * Set group name for automatic clustering
1137  */
1138 void connman_network_set_group(struct connman_network *network,
1139                                                         const char *group)
1140 {
1141         switch (network->type) {
1142         case CONNMAN_NETWORK_TYPE_UNKNOWN:
1143         case CONNMAN_NETWORK_TYPE_VENDOR:
1144                 return;
1145         case CONNMAN_NETWORK_TYPE_ETHERNET:
1146         case CONNMAN_NETWORK_TYPE_GADGET:
1147         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
1148         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
1149         case CONNMAN_NETWORK_TYPE_CELLULAR:
1150         case CONNMAN_NETWORK_TYPE_WIFI:
1151                 break;
1152         }
1153
1154         if (g_strcmp0(network->group, group) == 0) {
1155                 if (group)
1156                         __connman_service_update_from_network(network);
1157                 return;
1158         }
1159
1160         if (network->group) {
1161                 __connman_service_remove_from_network(network);
1162
1163                 g_free(network->group);
1164         }
1165
1166         network->group = g_strdup(group);
1167
1168         if (network->group)
1169                 network_probe(network);
1170 }
1171
1172 /**
1173  * connman_network_get_group:
1174  * @network: network structure
1175  *
1176  * Get group name for automatic clustering
1177  */
1178 const char *connman_network_get_group(struct connman_network *network)
1179 {
1180         return network->group;
1181 }
1182
1183 const char *__connman_network_get_ident(struct connman_network *network)
1184 {
1185         if (!network->device)
1186                 return NULL;
1187
1188         return connman_device_get_ident(network->device);
1189 }
1190
1191 bool __connman_network_get_weakness(struct connman_network *network)
1192 {
1193         switch (network->type) {
1194         case CONNMAN_NETWORK_TYPE_UNKNOWN:
1195         case CONNMAN_NETWORK_TYPE_VENDOR:
1196         case CONNMAN_NETWORK_TYPE_ETHERNET:
1197         case CONNMAN_NETWORK_TYPE_GADGET:
1198         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
1199         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
1200         case CONNMAN_NETWORK_TYPE_CELLULAR:
1201                 break;
1202         case CONNMAN_NETWORK_TYPE_WIFI:
1203                 if (network->strength > 0 && network->strength < 20)
1204                         return true;
1205                 break;
1206         }
1207
1208         return false;
1209 }
1210
1211 #if defined TIZEN_EXT
1212 void connman_network_set_connecting(struct connman_network *network)
1213 {
1214         DBG("set network connecting true");
1215         network->connecting = TRUE;
1216         return;
1217 }
1218 #endif
1219
1220 bool connman_network_get_connecting(struct connman_network *network)
1221 {
1222         return network->connecting;
1223 }
1224
1225 /**
1226  * connman_network_set_available:
1227  * @network: network structure
1228  * @available: availability state
1229  *
1230  * Change availability state of network (in range)
1231  */
1232 int connman_network_set_available(struct connman_network *network,
1233                                                 bool available)
1234 {
1235 #if !defined TIZEN_EXT
1236         DBG("network %p available %d", network, available);
1237 #endif
1238
1239         if (network->available == available)
1240                 return -EALREADY;
1241
1242         network->available = available;
1243
1244         return 0;
1245 }
1246
1247 /**
1248  * connman_network_get_available:
1249  * @network: network structure
1250  *
1251  * Get network available setting
1252  */
1253 bool connman_network_get_available(struct connman_network *network)
1254 {
1255         return network->available;
1256 }
1257
1258 #if defined TIZEN_EXT
1259 void connman_network_clear_associating(struct connman_network *network)
1260 {
1261         struct connman_service *service;
1262         enum connman_service_state state;
1263
1264         DBG("network %p", network);
1265
1266         network->connecting = FALSE;
1267         network->associating = FALSE;
1268
1269         service = connman_service_lookup_from_network(network);
1270         if (!service)
1271                 return;
1272
1273         state = __connman_service_ipconfig_get_state(service,
1274                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1275         if (state != CONNMAN_SERVICE_STATE_IDLE &&
1276                         state != CONNMAN_SERVICE_STATE_FAILURE)
1277                 __connman_service_ipconfig_indicate_state(service,
1278                                         CONNMAN_SERVICE_STATE_DISCONNECT,
1279                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1280
1281         state = __connman_service_ipconfig_get_state(service,
1282                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1283         if (state != CONNMAN_SERVICE_STATE_IDLE &&
1284                                 state != CONNMAN_SERVICE_STATE_FAILURE)
1285                 __connman_service_ipconfig_indicate_state(service,
1286                                         CONNMAN_SERVICE_STATE_DISCONNECT,
1287                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1288
1289         __connman_service_ipconfig_indicate_state(service,
1290                                                 CONNMAN_SERVICE_STATE_IDLE,
1291                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1292
1293         __connman_service_ipconfig_indicate_state(service,
1294                                                 CONNMAN_SERVICE_STATE_IDLE,
1295                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1296 }
1297
1298 static gboolean __connman_network_clear_associating_delayed(gpointer user_data)
1299 {
1300         GSList *list;
1301         gboolean found = FALSE;
1302         enum connman_service_state state_ipv4;
1303         enum connman_service_state state_ipv6;
1304         struct connman_service *service;
1305         struct connman_network *network = (struct connman_network *)user_data;
1306
1307         for (list = network_list; list != NULL; list = list->next) {
1308                 struct connman_network *item = list->data;
1309
1310                 if (item == network) {
1311                         found = TRUE;
1312                         break;
1313                 }
1314         }
1315
1316         if (found != TRUE)
1317                 return FALSE;
1318
1319         DBG("network %p name %s", network, network->name);
1320         service = connman_service_lookup_from_network(network);
1321
1322         state_ipv4 = __connman_service_ipconfig_get_state(service,
1323                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1324         state_ipv6 = __connman_service_ipconfig_get_state(service,
1325                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1326
1327         DBG("service %p state %d/%d", service, state_ipv4, state_ipv6);
1328
1329         if (network->associating == FALSE &&
1330                         state_ipv4 == CONNMAN_SERVICE_STATE_ASSOCIATION &&
1331                         state_ipv6 == CONNMAN_SERVICE_STATE_ASSOCIATION) {
1332                 __connman_service_ipconfig_indicate_state(service,
1333                                 CONNMAN_SERVICE_STATE_IDLE,
1334                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1335                 __connman_service_ipconfig_indicate_state(service,
1336                                 CONNMAN_SERVICE_STATE_IDLE,
1337                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1338         } else {
1339                 if (network->associating == FALSE) {
1340                         struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
1341                         enum connman_ipconfig_method ipv4_method, ipv6_method;
1342
1343                         ipconfig_ipv4 = __connman_service_get_ip4config(service);
1344                         ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4);
1345                         ipconfig_ipv6 = __connman_service_get_ip4config(service);
1346                         ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6);
1347
1348                         if((ipv4_method == CONNMAN_IPCONFIG_METHOD_UNKNOWN || ipv4_method == CONNMAN_IPCONFIG_METHOD_OFF) &&
1349                                         (state_ipv6 == CONNMAN_SERVICE_STATE_ASSOCIATION))
1350                                 __connman_service_ipconfig_indicate_state(service,
1351                                                 CONNMAN_SERVICE_STATE_IDLE,
1352                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1353                         if((ipv6_method == CONNMAN_IPCONFIG_METHOD_UNKNOWN || ipv6_method == CONNMAN_IPCONFIG_METHOD_OFF) &&
1354                                         (state_ipv4 == CONNMAN_SERVICE_STATE_ASSOCIATION))
1355                                 __connman_service_ipconfig_indicate_state(service,
1356                                                 CONNMAN_SERVICE_STATE_IDLE,
1357                                                 CONNMAN_IPCONFIG_TYPE_IPV4);
1358                 }
1359         }
1360
1361         return FALSE;
1362 }
1363 #endif
1364
1365 /**
1366  * connman_network_set_associating:
1367  * @network: network structure
1368  * @associating: associating state
1369  *
1370  * Change associating state of network
1371  */
1372 int connman_network_set_associating(struct connman_network *network,
1373                                                 bool associating)
1374 {
1375         DBG("network %p associating %d", network, associating);
1376
1377         if (network->associating == associating)
1378                 return -EALREADY;
1379
1380         network->associating = associating;
1381
1382         if (associating) {
1383                 struct connman_service *service;
1384
1385                 service = connman_service_lookup_from_network(network);
1386                 __connman_service_ipconfig_indicate_state(service,
1387                                         CONNMAN_SERVICE_STATE_ASSOCIATION,
1388                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1389                 __connman_service_ipconfig_indicate_state(service,
1390                                         CONNMAN_SERVICE_STATE_ASSOCIATION,
1391                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1392         }
1393
1394 #if defined TIZEN_EXT
1395         if (associating == FALSE &&
1396                         connman_network_get_bool(network, "WiFi.UseWPS") == FALSE)
1397                 g_timeout_add_seconds(1,
1398                                 __connman_network_clear_associating_delayed,
1399                                 network);
1400 #endif
1401
1402         return 0;
1403 }
1404
1405 static void set_associate_error(struct connman_network *network)
1406 {
1407         struct connman_service *service;
1408
1409         service = connman_service_lookup_from_network(network);
1410
1411 #if defined TIZEN_EXT
1412         __connman_service_indicate_error(service,
1413                                         CONNMAN_SERVICE_ERROR_AUTH_FAILED);
1414 #else
1415         __connman_service_indicate_error(service,
1416                                         CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
1417 #endif
1418 }
1419
1420 static void set_configure_error(struct connman_network *network)
1421 {
1422         struct connman_service *service;
1423
1424         service = connman_service_lookup_from_network(network);
1425
1426         __connman_service_indicate_error(service,
1427                                         CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
1428 }
1429
1430 static void set_invalid_key_error(struct connman_network *network)
1431 {
1432         struct connman_service *service;
1433
1434         service = connman_service_lookup_from_network(network);
1435
1436 #if defined TIZEN_EXT
1437         if (service)
1438                 __connman_service_set_favorite(service, false);
1439 #endif
1440         __connman_service_indicate_error(service,
1441                                         CONNMAN_SERVICE_ERROR_INVALID_KEY);
1442 }
1443
1444 static void set_connect_error(struct connman_network *network)
1445 {
1446         struct connman_service *service;
1447
1448         service = connman_service_lookup_from_network(network);
1449
1450         __connman_service_indicate_error(service,
1451                                         CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
1452 }
1453
1454 static void set_blocked_error(struct connman_network *network)
1455 {
1456         struct connman_service *service;
1457
1458         service = connman_service_lookup_from_network(network);
1459
1460         __connman_service_indicate_error(service,
1461                                         CONNMAN_SERVICE_ERROR_BLOCKED);
1462 }
1463
1464
1465 #if defined TIZEN_EXT
1466 static void set_dhcp_error(struct connman_network *network)
1467 {
1468         struct connman_service *service;
1469
1470         if (network->associating != FALSE)
1471                 network->associating = FALSE;
1472
1473         service = connman_service_lookup_from_network(network);
1474
1475         __connman_service_indicate_error(service,
1476                                         CONNMAN_SERVICE_ERROR_DHCP_FAILED);
1477 }
1478 #endif
1479
1480 void connman_network_set_ipv4_method(struct connman_network *network,
1481                                         enum connman_ipconfig_method method)
1482 {
1483         struct connman_service *service;
1484         struct connman_ipconfig *ipconfig;
1485
1486         service = connman_service_lookup_from_network(network);
1487         if (!service)
1488                 return;
1489
1490         ipconfig = __connman_service_get_ip4config(service);
1491         if (!ipconfig)
1492                 return;
1493
1494         __connman_ipconfig_set_method(ipconfig, method);
1495 }
1496
1497 void connman_network_set_ipv6_method(struct connman_network *network,
1498                                         enum connman_ipconfig_method method)
1499 {
1500         struct connman_service *service;
1501         struct connman_ipconfig *ipconfig;
1502
1503         service = connman_service_lookup_from_network(network);
1504         if (!service)
1505                 return;
1506
1507         ipconfig = __connman_service_get_ip6config(service);
1508         if (!ipconfig)
1509                 return;
1510
1511         __connman_ipconfig_set_method(ipconfig, method);
1512 }
1513
1514 void connman_network_set_error(struct connman_network *network,
1515                                         enum connman_network_error error)
1516 {
1517         DBG("network %p error %d", network, error);
1518
1519         switch (error) {
1520         case CONNMAN_NETWORK_ERROR_UNKNOWN:
1521                 return;
1522         case CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL:
1523                 set_associate_error(network);
1524                 break;
1525         case CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL:
1526                 set_configure_error(network);
1527                 break;
1528         case CONNMAN_NETWORK_ERROR_INVALID_KEY:
1529                 set_invalid_key_error(network);
1530                 break;
1531         case CONNMAN_NETWORK_ERROR_CONNECT_FAIL:
1532                 set_connect_error(network);
1533                 break;
1534 #if defined TIZEN_EXT
1535         case CONNMAN_NETWORK_ERROR_DHCP_FAIL:
1536                 set_dhcp_error(network);
1537                 break;
1538 #endif
1539
1540         case CONNMAN_NETWORK_ERROR_BLOCKED:
1541                 set_blocked_error(network);
1542                 break;
1543
1544         }
1545
1546         __connman_network_disconnect(network);
1547 }
1548
1549 /**
1550  * connman_network_set_connected:
1551  * @network: network structure
1552  * @connected: connected state
1553  *
1554  * Change connected state of network
1555  */
1556 int connman_network_set_connected(struct connman_network *network,
1557                                                 bool connected)
1558 {
1559         DBG("network %p connected %d/%d connecting %d associating %d",
1560                 network, network->connected, connected, network->connecting,
1561                 network->associating);
1562
1563         if ((network->connecting || network->associating) &&
1564                                                         !connected) {
1565                 connman_network_set_error(network,
1566                                         CONNMAN_NETWORK_ERROR_CONNECT_FAIL);
1567                 return 0;
1568         }
1569
1570         if (network->connected == connected)
1571                 return -EALREADY;
1572
1573         if (!connected)
1574                 set_disconnected(network);
1575         else
1576                 set_connected(network);
1577
1578         return 0;
1579 }
1580
1581 /**
1582  * connman_network_get_connected:
1583  * @network: network structure
1584  *
1585  * Get network connection status
1586  */
1587 bool connman_network_get_connected(struct connman_network *network)
1588 {
1589         return network->connected;
1590 }
1591
1592 /**
1593  * connman_network_get_associating:
1594  * @network: network structure
1595  *
1596  * Get network associating status
1597  */
1598 bool connman_network_get_associating(struct connman_network *network)
1599 {
1600         return network->associating;
1601 }
1602
1603 void connman_network_clear_hidden(void *user_data)
1604 {
1605         if (!user_data)
1606                 return;
1607
1608         DBG("user_data %p", user_data);
1609
1610         /*
1611          * Hidden service does not have a connect timeout so
1612          * we do not need to remove it. We can just return
1613          * error to the caller telling that we could not find
1614          * any network that we could connect to.
1615          */
1616         connman_dbus_reply_pending(user_data, EIO, NULL);
1617 }
1618
1619 int connman_network_connect_hidden(struct connman_network *network,
1620                         char *identity, char *passphrase, void *user_data)
1621 {
1622         int err = 0;
1623         struct connman_service *service;
1624
1625         service = connman_service_lookup_from_network(network);
1626
1627         DBG("network %p service %p user_data %p", network, service, user_data);
1628
1629         if (!service)
1630                 return -EINVAL;
1631
1632         if (identity)
1633                 __connman_service_set_agent_identity(service, identity);
1634
1635         if (passphrase)
1636                 err = __connman_service_set_passphrase(service, passphrase);
1637
1638         if (err == -ENOKEY) {
1639                 __connman_service_indicate_error(service,
1640                                         CONNMAN_SERVICE_ERROR_INVALID_KEY);
1641                 goto out;
1642         } else {
1643                 __connman_service_set_hidden(service);
1644                 __connman_service_set_hidden_data(service, user_data);
1645                 return __connman_service_connect(service,
1646                                         CONNMAN_SERVICE_CONNECT_REASON_USER);
1647         }
1648
1649 out:
1650         __connman_service_return_error(service, -err, user_data);
1651         return err;
1652 }
1653
1654 /**
1655  * __connman_network_connect:
1656  * @network: network structure
1657  *
1658  * Connect network
1659  */
1660 int __connman_network_connect(struct connman_network *network)
1661 {
1662         int err;
1663
1664         DBG("network %p", network);
1665
1666         if (network->connected)
1667                 return -EISCONN;
1668
1669         if (network->connecting || network->associating)
1670                 return -EALREADY;
1671
1672         if (!network->driver)
1673                 return -EUNATCH;
1674
1675         if (!network->driver->connect)
1676                 return -ENOSYS;
1677
1678         if (!network->device)
1679                 return -ENODEV;
1680
1681         network->connecting = true;
1682
1683 #if defined TIZEN_EXT
1684         if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR)
1685 #endif
1686         __connman_device_disconnect(network->device);
1687 #if defined TIZEN_EXT
1688         DBG("ConnMan, Connect Request [%s]", network->name);
1689 #endif
1690         err = network->driver->connect(network);
1691         if (err < 0) {
1692                 if (err == -EINPROGRESS) {
1693 #if defined TIZEN_EXT
1694                         if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR)
1695 #endif
1696                         connman_network_set_associating(network, true);
1697                 } else
1698                         network->connecting = false;
1699
1700                 return err;
1701         }
1702
1703         set_connected(network);
1704
1705         return err;
1706 }
1707
1708 /**
1709  * __connman_network_disconnect:
1710  * @network: network structure
1711  *
1712  * Disconnect network
1713  */
1714 int __connman_network_disconnect(struct connman_network *network)
1715 {
1716         int err = 0;
1717
1718         DBG("network %p", network);
1719
1720         if (!network->connected && !network->connecting &&
1721                                                 !network->associating)
1722                 return -ENOTCONN;
1723
1724         if (!network->driver)
1725                 return -EUNATCH;
1726
1727         network->connecting = false;
1728 #if defined TIZEN_EXT
1729         DBG("ConnMan, Disconnect request");
1730 #endif
1731         if (network->driver->disconnect)
1732                 err = network->driver->disconnect(network);
1733
1734         if (err != -EINPROGRESS)
1735                 set_disconnected(network);
1736
1737         return err;
1738 }
1739
1740 int __connman_network_clear_ipconfig(struct connman_network *network,
1741                                         struct connman_ipconfig *ipconfig)
1742 {
1743         struct connman_service *service;
1744         struct connman_ipconfig *ipconfig_ipv4;
1745         enum connman_ipconfig_method method;
1746         enum connman_ipconfig_type type;
1747
1748         service = connman_service_lookup_from_network(network);
1749         if (!service)
1750                 return -EINVAL;
1751
1752         ipconfig_ipv4 = __connman_service_get_ip4config(service);
1753         method = __connman_ipconfig_get_method(ipconfig);
1754         type = __connman_ipconfig_get_config_type(ipconfig);
1755
1756         switch (method) {
1757         case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1758         case CONNMAN_IPCONFIG_METHOD_OFF:
1759         case CONNMAN_IPCONFIG_METHOD_FIXED:
1760                 return -EINVAL;
1761         case CONNMAN_IPCONFIG_METHOD_AUTO:
1762                 release_dhcpv6(network);
1763                 break;
1764         case CONNMAN_IPCONFIG_METHOD_MANUAL:
1765                 __connman_ipconfig_address_remove(ipconfig);
1766                 break;
1767         case CONNMAN_IPCONFIG_METHOD_DHCP:
1768                 __connman_dhcp_stop(ipconfig_ipv4);
1769                 break;
1770         }
1771
1772         if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1773                 __connman_service_ipconfig_indicate_state(service,
1774                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
1775                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1776         else if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1777                 __connman_service_ipconfig_indicate_state(service,
1778                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
1779                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1780
1781         return 0;
1782 }
1783
1784 #if defined TIZEN_EXT
1785 void __connman_network_set_auto_ipv6_gateway(char *gateway, void *user_data)
1786 {
1787         DBG("");
1788
1789         struct connman_network *network = user_data;
1790         struct connman_service *service;
1791         struct connman_ipconfig *ipconfig = NULL;
1792
1793         service = connman_service_lookup_from_network(network);
1794         if (service == NULL)
1795                 return;
1796
1797         ipconfig = __connman_service_get_ipconfig(service, AF_INET6);
1798         if (ipconfig == NULL)
1799                 return;
1800
1801         __connman_ipconfig_set_gateway(ipconfig, gateway);
1802
1803         return;
1804 }
1805 #endif
1806
1807 int __connman_network_enable_ipconfig(struct connman_network *network,
1808                                 struct connman_ipconfig *ipconfig)
1809 {
1810         int r = 0;
1811         enum connman_ipconfig_type type;
1812         enum connman_ipconfig_method method;
1813 #if defined TIZEN_EXT
1814         struct connman_service *service;
1815 #endif
1816
1817         if (!network || !ipconfig)
1818                 return -EINVAL;
1819
1820         type = __connman_ipconfig_get_config_type(ipconfig);
1821
1822         switch (type) {
1823         case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
1824         case CONNMAN_IPCONFIG_TYPE_ALL:
1825                 return -ENOSYS;
1826
1827         case CONNMAN_IPCONFIG_TYPE_IPV6:
1828                 set_configuration(network, type);
1829
1830                 method = __connman_ipconfig_get_method(ipconfig);
1831
1832                 DBG("ipv6 ipconfig method %d", method);
1833
1834                 switch (method) {
1835                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1836                         break;
1837
1838                 case CONNMAN_IPCONFIG_METHOD_OFF:
1839                         __connman_ipconfig_disable_ipv6(ipconfig);
1840                         break;
1841
1842                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1843 #if defined TIZEN_EXT
1844                 service = connman_service_lookup_from_network(network);
1845
1846                 if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR)
1847                         __connman_service_ipconfig_indicate_state(service,
1848                                 CONNMAN_SERVICE_STATE_CONFIGURATION,
1849                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1850 #endif
1851                         autoconf_ipv6_set(network);
1852                         break;
1853
1854                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1855                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1856                         r = manual_ipv6_set(network, ipconfig);
1857                         break;
1858
1859                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1860                         r = -ENOSYS;
1861                         break;
1862                 }
1863
1864                 break;
1865
1866         case CONNMAN_IPCONFIG_TYPE_IPV4:
1867                 set_configuration(network, type);
1868
1869                 method = __connman_ipconfig_get_method(ipconfig);
1870
1871                 DBG("ipv4 ipconfig method %d", method);
1872
1873                 switch (method) {
1874                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1875                 case CONNMAN_IPCONFIG_METHOD_OFF:
1876                         break;
1877
1878                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1879                         r = -ENOSYS;
1880                         break;
1881
1882                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1883                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1884                         r = set_connected_manual(network);
1885                         break;
1886
1887                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1888                         r = set_connected_dhcp(network);
1889                         break;
1890                 }
1891
1892                 break;
1893         }
1894
1895         if (r < 0)
1896                 connman_network_set_error(network,
1897                                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
1898
1899         return r;
1900 }
1901
1902 int connman_network_set_ipaddress(struct connman_network *network,
1903                                         struct connman_ipaddress *ipaddress)
1904 {
1905         struct connman_service *service;
1906         struct connman_ipconfig *ipconfig = NULL;
1907
1908         DBG("network %p", network);
1909
1910         service = connman_service_lookup_from_network(network);
1911         if (!service)
1912                 return -EINVAL;
1913
1914         ipconfig = __connman_service_get_ipconfig(service, ipaddress->family);
1915         if (!ipconfig)
1916                 return -EINVAL;
1917
1918         __connman_ipconfig_set_local(ipconfig, ipaddress->local);
1919         __connman_ipconfig_set_peer(ipconfig, ipaddress->peer);
1920         __connman_ipconfig_set_broadcast(ipconfig, ipaddress->broadcast);
1921         __connman_ipconfig_set_prefixlen(ipconfig, ipaddress->prefixlen);
1922         __connman_ipconfig_set_gateway(ipconfig, ipaddress->gateway);
1923
1924         return 0;
1925 }
1926
1927 #if defined TIZEN_EXT
1928 /*
1929  * Description: Network client requires additional wifi specific info
1930  */
1931 int connman_network_set_bssid(struct connman_network *network,
1932                                 const unsigned char *bssid)
1933 {
1934         int i = 0;
1935
1936         if (bssid == NULL)
1937                 return -EINVAL;
1938
1939         DBG("network %p bssid %02x:%02x:%02x:%02x:%02x:%02x", network,
1940                         bssid[0], bssid[1], bssid[2],
1941                         bssid[3], bssid[4], bssid[5]);
1942
1943         for (;i < WIFI_BSSID_LEN_MAX;i++)
1944                 network->wifi.bssid[i] = bssid[i];
1945
1946         return 0;
1947 }
1948
1949 unsigned char *connman_network_get_bssid(struct connman_network *network)
1950 {
1951         return (unsigned char *)network->wifi.bssid;
1952 }
1953
1954 int connman_network_set_maxrate(struct connman_network *network,
1955                                 unsigned int maxrate)
1956 {
1957 #if !defined TIZEN_EXT
1958         DBG("network %p maxrate %d", network, maxrate);
1959 #endif
1960
1961         network->wifi.maxrate = maxrate;
1962
1963         return 0;
1964 }
1965
1966 unsigned int connman_network_get_maxrate(struct connman_network *network)
1967 {
1968         return network->wifi.maxrate;
1969 }
1970
1971 int connman_network_set_enc_mode(struct connman_network *network,
1972                                 const char *encryption_mode)
1973 {
1974         if (encryption_mode == NULL)
1975                 return -EINVAL;
1976
1977         DBG("network %p encryption mode %s", network, encryption_mode);
1978
1979         g_strlcpy(network->wifi.encryption_mode, encryption_mode,
1980                                         WIFI_ENCYPTION_MODE_LEN_MAX);
1981
1982         return 0;
1983 }
1984
1985 const char *connman_network_get_enc_mode(struct connman_network *network)
1986 {
1987         return (const char *)network->wifi.encryption_mode;
1988 }
1989
1990 int connman_network_set_rsn_mode(struct connman_network *network,
1991                                 bool rsn_mode)
1992 {
1993         network->wifi.rsn_mode = rsn_mode;
1994
1995         return 0;
1996 }
1997
1998 int connman_network_set_proxy(struct connman_network *network,
1999                                 const char *proxies)
2000 {
2001         struct connman_service *service;
2002
2003         DBG("network %p proxies %s", network, proxies);
2004
2005         service = connman_service_lookup_from_network(network);
2006         if (service == NULL)
2007                 return -EINVAL;
2008
2009         __connman_service_set_proxy(service, proxies);
2010
2011         connman_service_set_proxy_method(service,
2012                                 CONNMAN_SERVICE_PROXY_METHOD_MANUAL);
2013
2014         return 0;
2015 }
2016
2017 int connman_network_set_is_hs20AP(struct connman_network *network,
2018                                 unsigned int isHS20AP)
2019 {
2020         if (!network)
2021                 return 0;
2022
2023         network->wifi.isHS20AP = isHS20AP;
2024
2025         return 0;
2026 }
2027
2028 unsigned int connman_network_get_is_hs20AP(struct connman_network *network)
2029 {
2030         if (!network)
2031                 return 0;
2032
2033         return network->wifi.isHS20AP;
2034 }
2035
2036 int connman_network_set_keymgmt(struct connman_network *network,
2037                                 unsigned int keymgmt)
2038 {
2039         if (network == NULL)
2040                 return 0;
2041
2042         network->wifi.keymgmt = keymgmt;
2043
2044         return 0;
2045 }
2046
2047 unsigned int connman_network_get_keymgmt(struct connman_network *network)
2048 {
2049         if (network == NULL)
2050                 return 0;
2051
2052         return network->wifi.keymgmt;
2053 }
2054
2055 int connman_network_set_disconnect_reason(struct connman_network *network,
2056                                 int reason_code)
2057 {
2058         if (network == NULL)
2059                 return 0;
2060
2061         network->wifi.disconnect_reason = reason_code;
2062
2063         return 0;
2064 }
2065
2066 int connman_network_get_disconnect_reason(struct connman_network *network)
2067 {
2068         if (network == NULL)
2069                 return 0;
2070
2071         return network->wifi.disconnect_reason;
2072 }
2073
2074 int connman_network_set_assoc_status_code(struct connman_network *network,
2075                                 int assoc_status_code)
2076 {
2077
2078         if (network == NULL)
2079                 return 0;
2080
2081         network->wifi.assoc_status_code = assoc_status_code;
2082         return 0;
2083 }
2084
2085 int connman_network_get_assoc_status_code(struct connman_network *network)
2086 {
2087         if (network == NULL)
2088                 return 0;
2089
2090         return network->wifi.assoc_status_code;
2091 }
2092
2093 #endif
2094
2095 int connman_network_set_nameservers(struct connman_network *network,
2096                                 const char *nameservers)
2097 {
2098         struct connman_service *service;
2099         char **nameservers_array;
2100         int i;
2101
2102         DBG("network %p nameservers %s", network, nameservers);
2103
2104         service = connman_service_lookup_from_network(network);
2105         if (!service)
2106                 return -EINVAL;
2107
2108         __connman_service_nameserver_clear(service);
2109
2110         if (!nameservers)
2111                 return 0;
2112
2113         nameservers_array = g_strsplit(nameservers, " ", 0);
2114
2115         for (i = 0; nameservers_array[i]; i++) {
2116 #if defined TIZEN_EXT
2117                 __connman_service_nameserver_append(service,
2118                                                 nameservers_array[i], false,
2119                                                 CONNMAN_IPCONFIG_TYPE_ALL);
2120 #else
2121                 __connman_service_nameserver_append(service,
2122                                                 nameservers_array[i], false);
2123 #endif
2124         }
2125
2126         g_strfreev(nameservers_array);
2127
2128         return 0;
2129 }
2130
2131 int connman_network_set_domain(struct connman_network *network,
2132                                 const char *domain)
2133 {
2134         struct connman_service *service;
2135
2136         DBG("network %p domain %s", network, domain);
2137
2138         service = connman_service_lookup_from_network(network);
2139         if (!service)
2140                 return -EINVAL;
2141
2142         __connman_service_set_domainname(service, domain);
2143
2144         return 0;
2145 }
2146
2147 /**
2148  * connman_network_set_name:
2149  * @network: network structure
2150  * @name: name value
2151  *
2152  * Set display name value for network
2153  */
2154 int connman_network_set_name(struct connman_network *network,
2155                                                         const char *name)
2156 {
2157         DBG("network %p name %s", network, name);
2158
2159         g_free(network->name);
2160         network->name = g_strdup(name);
2161
2162         return 0;
2163 }
2164
2165 /**
2166  * connman_network_set_strength:
2167  * @network: network structure
2168  * @strength: strength value
2169  *
2170  * Set signal strength value for network
2171  */
2172
2173 int connman_network_set_strength(struct connman_network *network,
2174                                                 uint8_t strength)
2175 {
2176 #if !defined TIZEN_EXT
2177         DBG("network %p strengh %d", network, strength);
2178 #endif
2179
2180         network->strength = strength;
2181
2182         return 0;
2183 }
2184
2185 uint8_t connman_network_get_strength(struct connman_network *network)
2186 {
2187         return network->strength;
2188 }
2189
2190 int connman_network_set_frequency(struct connman_network *network,
2191                                                 uint16_t frequency)
2192 {
2193 #if !defined TIZEN_EXT
2194         DBG("network %p frequency %d", network, frequency);
2195 #endif
2196
2197         network->frequency = frequency;
2198
2199         return 0;
2200 }
2201
2202 uint16_t connman_network_get_frequency(struct connman_network *network)
2203 {
2204         return network->frequency;
2205 }
2206
2207 int connman_network_set_wifi_channel(struct connman_network *network,
2208                                                 uint16_t channel)
2209 {
2210         DBG("network %p wifi channel %d", network, channel);
2211
2212         network->wifi.channel = channel;
2213
2214         return 0;
2215 }
2216
2217 uint16_t connman_network_get_wifi_channel(struct connman_network *network)
2218 {
2219         return network->wifi.channel;
2220 }
2221
2222 /**
2223  * connman_network_set_string:
2224  * @network: network structure
2225  * @key: unique identifier
2226  * @value: string value
2227  *
2228  * Set string value for specific key
2229  */
2230 int connman_network_set_string(struct connman_network *network,
2231                                         const char *key, const char *value)
2232 {
2233 #if !defined TIZEN_EXT
2234         DBG("network %p key %s value %s", network, key, value);
2235 #endif
2236
2237         if (g_strcmp0(key, "Name") == 0)
2238                 return connman_network_set_name(network, value);
2239
2240         if (g_str_equal(key, "Path")) {
2241                 g_free(network->path);
2242                 network->path = g_strdup(value);
2243         } else if (g_str_equal(key, "Node")) {
2244                 g_free(network->node);
2245                 network->node = g_strdup(value);
2246         } else if (g_str_equal(key, "WiFi.Mode")) {
2247                 g_free(network->wifi.mode);
2248                 network->wifi.mode = g_strdup(value);
2249         } else if (g_str_equal(key, "WiFi.Security")) {
2250                 g_free(network->wifi.security);
2251                 network->wifi.security = g_strdup(value);
2252         } else if (g_str_equal(key, "WiFi.Passphrase")) {
2253 #if defined TIZEN_EXT
2254                 DBG("ConnMan, %p key %s", network, key);
2255 #endif
2256                 g_free(network->wifi.passphrase);
2257                 network->wifi.passphrase = g_strdup(value);
2258         } else if (g_str_equal(key, "WiFi.EAP")) {
2259                 g_free(network->wifi.eap);
2260                 network->wifi.eap = g_strdup(value);
2261         } else if (g_str_equal(key, "WiFi.Identity")) {
2262                 g_free(network->wifi.identity);
2263                 network->wifi.identity = g_strdup(value);
2264         } else if (g_str_equal(key, "WiFi.AgentIdentity")) {
2265                 g_free(network->wifi.agent_identity);
2266                 network->wifi.agent_identity = g_strdup(value);
2267         } else if (g_str_equal(key, "WiFi.CACertFile")) {
2268                 g_free(network->wifi.ca_cert_path);
2269                 network->wifi.ca_cert_path = g_strdup(value);
2270         } else if (g_str_equal(key, "WiFi.ClientCertFile")) {
2271                 g_free(network->wifi.client_cert_path);
2272                 network->wifi.client_cert_path = g_strdup(value);
2273         } else if (g_str_equal(key, "WiFi.PrivateKeyFile")) {
2274                 g_free(network->wifi.private_key_path);
2275                 network->wifi.private_key_path = g_strdup(value);
2276         } else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase")) {
2277                 g_free(network->wifi.private_key_passphrase);
2278                 network->wifi.private_key_passphrase = g_strdup(value);
2279         } else if (g_str_equal(key, "WiFi.Phase2")) {
2280                 g_free(network->wifi.phase2_auth);
2281                 network->wifi.phase2_auth = g_strdup(value);
2282         } else if (g_str_equal(key, "WiFi.PinWPS")) {
2283                 g_free(network->wifi.pin_wps);
2284                 network->wifi.pin_wps = g_strdup(value);
2285         } else {
2286                 return -EINVAL;
2287         }
2288
2289         return 0;
2290 }
2291
2292 /**
2293  * connman_network_get_string:
2294  * @network: network structure
2295  * @key: unique identifier
2296  *
2297  * Get string value for specific key
2298  */
2299 const char *connman_network_get_string(struct connman_network *network,
2300                                                         const char *key)
2301 {
2302 #if !defined TIZEN_EXT
2303         DBG("network %p key %s", network, key);
2304 #endif
2305
2306         if (g_str_equal(key, "Path"))
2307                 return network->path;
2308         else if (g_str_equal(key, "Name"))
2309                 return network->name;
2310         else if (g_str_equal(key, "Node"))
2311                 return network->node;
2312         else if (g_str_equal(key, "WiFi.Mode"))
2313                 return network->wifi.mode;
2314         else if (g_str_equal(key, "WiFi.Security"))
2315 #if defined TIZEN_EXT
2316                 if (network->wifi.rsn_mode != true ||
2317                     g_str_equal(network->wifi.security, "ieee8021x"))
2318                         return network->wifi.security;
2319                 else
2320                         return "rsn";
2321 #else
2322                 return network->wifi.security;
2323 #endif
2324         else if (g_str_equal(key, "WiFi.Passphrase"))
2325                 return network->wifi.passphrase;
2326         else if (g_str_equal(key, "WiFi.EAP"))
2327                 return network->wifi.eap;
2328         else if (g_str_equal(key, "WiFi.Identity"))
2329                 return network->wifi.identity;
2330         else if (g_str_equal(key, "WiFi.AgentIdentity"))
2331                 return network->wifi.agent_identity;
2332         else if (g_str_equal(key, "WiFi.CACertFile"))
2333                 return network->wifi.ca_cert_path;
2334         else if (g_str_equal(key, "WiFi.ClientCertFile"))
2335                 return network->wifi.client_cert_path;
2336         else if (g_str_equal(key, "WiFi.PrivateKeyFile"))
2337                 return network->wifi.private_key_path;
2338         else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase"))
2339                 return network->wifi.private_key_passphrase;
2340         else if (g_str_equal(key, "WiFi.Phase2"))
2341                 return network->wifi.phase2_auth;
2342         else if (g_str_equal(key, "WiFi.PinWPS"))
2343                 return network->wifi.pin_wps;
2344
2345         return NULL;
2346 }
2347
2348 /**
2349  * connman_network_set_bool:
2350  * @network: network structure
2351  * @key: unique identifier
2352  * @value: boolean value
2353  *
2354  * Set boolean value for specific key
2355  */
2356 int connman_network_set_bool(struct connman_network *network,
2357                                         const char *key, bool value)
2358 {
2359 #if !defined TIZEN_EXT
2360         DBG("network %p key %s value %d", network, key, value);
2361 #endif
2362
2363         if (g_strcmp0(key, "Roaming") == 0)
2364                 network->roaming = value;
2365         else if (g_strcmp0(key, "WiFi.WPS") == 0)
2366                 network->wifi.wps = value;
2367         else if (g_strcmp0(key, "WiFi.UseWPS") == 0)
2368                 network->wifi.use_wps = value;
2369 #if defined TIZEN_EXT
2370         else if (g_strcmp0(key, "DefaultInternet") == 0)
2371                 network->default_internet = value;
2372 #endif
2373
2374         return -EINVAL;
2375 }
2376
2377 /**
2378  * connman_network_get_bool:
2379  * @network: network structure
2380  * @key: unique identifier
2381  *
2382  * Get boolean value for specific key
2383  */
2384 bool connman_network_get_bool(struct connman_network *network,
2385                                                         const char *key)
2386 {
2387 #if !defined TIZEN_EXT
2388         DBG("network %p key %s", network, key);
2389 #endif
2390
2391         if (g_str_equal(key, "Roaming"))
2392                 return network->roaming;
2393         else if (g_str_equal(key, "WiFi.WPS"))
2394                 return network->wifi.wps;
2395         else if (g_str_equal(key, "WiFi.UseWPS"))
2396                 return network->wifi.use_wps;
2397 #if defined TIZEN_EXT
2398         else if (g_str_equal(key, "DefaultInternet"))
2399                 return network->default_internet;
2400 #endif
2401
2402         return false;
2403 }
2404
2405 /**
2406  * connman_network_set_blob:
2407  * @network: network structure
2408  * @key: unique identifier
2409  * @data: blob data
2410  * @size: blob size
2411  *
2412  * Set binary blob value for specific key
2413  */
2414 int connman_network_set_blob(struct connman_network *network,
2415                         const char *key, const void *data, unsigned int size)
2416 {
2417 #if !defined TIZEN_EXT
2418         DBG("network %p key %s size %d", network, key, size);
2419 #endif
2420
2421         if (g_str_equal(key, "WiFi.SSID")) {
2422                 g_free(network->wifi.ssid);
2423                 network->wifi.ssid = g_try_malloc(size);
2424                 if (network->wifi.ssid) {
2425                         memcpy(network->wifi.ssid, data, size);
2426                         network->wifi.ssid_len = size;
2427                 } else
2428                         network->wifi.ssid_len = 0;
2429 #if defined TIZEN_EXT
2430         } else if (g_str_equal(key, "WiFi.Vsie")){
2431                 g_free(network->wifi.wifi_vsie);
2432                 network->wifi.wifi_vsie = g_try_malloc(size);
2433                 if (network->wifi.wifi_vsie) {
2434                         memcpy(network->wifi.wifi_vsie, data, size);
2435                         network->wifi.wifi_vsie_len = size;
2436                 } else
2437                         network->wifi.wifi_vsie_len = 0;
2438 #endif
2439         } else {
2440                 return -EINVAL;
2441         }
2442
2443         return 0;
2444 }
2445
2446 /**
2447  * connman_network_get_blob:
2448  * @network: network structure
2449  * @key: unique identifier
2450  * @size: pointer to blob size
2451  *
2452  * Get binary blob value for specific key
2453  */
2454 const void *connman_network_get_blob(struct connman_network *network,
2455                                         const char *key, unsigned int *size)
2456 {
2457         DBG("network %p key %s", network, key);
2458
2459         if (g_str_equal(key, "WiFi.SSID")) {
2460                 if (size)
2461                         *size = network->wifi.ssid_len;
2462                 return network->wifi.ssid;
2463         }
2464
2465 #if defined TIZEN_EXT
2466         if (g_str_equal(key, "WiFi.Vsie")) {
2467                 if (size) {
2468                         *size = network->wifi.wifi_vsie_len;
2469                         DBG("network %p key %s size=%d", network, key, *size);
2470                 }
2471
2472                 return network->wifi.wifi_vsie;
2473         }
2474 #endif
2475
2476         return NULL;
2477 }
2478
2479 void __connman_network_set_device(struct connman_network *network,
2480                                         struct connman_device *device)
2481 {
2482         if (network->device == device)
2483                 return;
2484
2485         if (network->device)
2486                 network_remove(network);
2487
2488         network->device = device;
2489
2490         if (network->device)
2491                 network_probe(network);
2492 }
2493
2494 /**
2495  * connman_network_get_device:
2496  * @network: network structure
2497  *
2498  * Get parent device of network
2499  */
2500 struct connman_device *connman_network_get_device(struct connman_network *network)
2501 {
2502         return network->device;
2503 }
2504
2505 /**
2506  * connman_network_get_data:
2507  * @network: network structure
2508  *
2509  * Get private network data pointer
2510  */
2511 void *connman_network_get_data(struct connman_network *network)
2512 {
2513         return network->driver_data;
2514 }
2515
2516 /**
2517  * connman_network_set_data:
2518  * @network: network structure
2519  * @data: data pointer
2520  *
2521  * Set private network data pointer
2522  */
2523 void connman_network_set_data(struct connman_network *network, void *data)
2524 {
2525         network->driver_data = data;
2526 }
2527
2528 void connman_network_update(struct connman_network *network)
2529 {
2530         switch (network->type) {
2531         case CONNMAN_NETWORK_TYPE_UNKNOWN:
2532         case CONNMAN_NETWORK_TYPE_VENDOR:
2533                 return;
2534         case CONNMAN_NETWORK_TYPE_ETHERNET:
2535         case CONNMAN_NETWORK_TYPE_GADGET:
2536         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
2537         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
2538         case CONNMAN_NETWORK_TYPE_CELLULAR:
2539         case CONNMAN_NETWORK_TYPE_WIFI:
2540                 break;
2541         }
2542
2543         if (network->group)
2544                 __connman_service_update_from_network(network);
2545 }
2546
2547 int __connman_network_init(void)
2548 {
2549         DBG("");
2550
2551         return 0;
2552 }
2553
2554 void __connman_network_cleanup(void)
2555 {
2556         DBG("");
2557 }