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