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