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