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