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