[SPIN] network: enable DHCP failure.
[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_network_clear_associating(network);
1317
1318         return FALSE;
1319 }
1320 #endif
1321
1322 /**
1323  * connman_network_set_associating:
1324  * @network: network structure
1325  * @associating: associating state
1326  *
1327  * Change associating state of network
1328  */
1329 int connman_network_set_associating(struct connman_network *network,
1330                                                 bool associating)
1331 {
1332         DBG("network %p associating %d", network, associating);
1333
1334         if (network->associating == associating)
1335                 return -EALREADY;
1336
1337         network->associating = associating;
1338
1339         if (associating) {
1340                 struct connman_service *service;
1341
1342                 service = connman_service_lookup_from_network(network);
1343                 __connman_service_ipconfig_indicate_state(service,
1344                                         CONNMAN_SERVICE_STATE_ASSOCIATION,
1345                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1346                 __connman_service_ipconfig_indicate_state(service,
1347                                         CONNMAN_SERVICE_STATE_ASSOCIATION,
1348                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1349         }
1350
1351 #if defined TIZEN_EXT
1352         if (associating == FALSE &&
1353                         connman_network_get_bool(network, "WiFi.UseWPS") == FALSE)
1354                 g_timeout_add_seconds(1,
1355                                 __connman_network_clear_associating_delayed,
1356                                 network);
1357 #endif
1358
1359         return 0;
1360 }
1361
1362 static void set_associate_error(struct connman_network *network)
1363 {
1364         struct connman_service *service;
1365
1366         service = connman_service_lookup_from_network(network);
1367
1368         __connman_service_indicate_error(service,
1369                                         CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
1370 }
1371
1372 static void set_configure_error(struct connman_network *network)
1373 {
1374         struct connman_service *service;
1375
1376         service = connman_service_lookup_from_network(network);
1377
1378         __connman_service_indicate_error(service,
1379                                         CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
1380 }
1381
1382 static void set_invalid_key_error(struct connman_network *network)
1383 {
1384         struct connman_service *service;
1385
1386         service = connman_service_lookup_from_network(network);
1387
1388         __connman_service_indicate_error(service,
1389                                         CONNMAN_SERVICE_ERROR_INVALID_KEY);
1390 }
1391
1392 static void set_connect_error(struct connman_network *network)
1393 {
1394         struct connman_service *service;
1395
1396         service = connman_service_lookup_from_network(network);
1397
1398         __connman_service_indicate_error(service,
1399                                         CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
1400 }
1401
1402 #if defined TIZEN_EXT
1403 static void set_dhcp_error(struct connman_network *network)
1404 {
1405         struct connman_service *service;
1406
1407         if (network->associating != FALSE)
1408                 network->associating = FALSE;
1409
1410         service = connman_service_lookup_from_network(network);
1411
1412         __connman_service_indicate_error(service,
1413                                         CONNMAN_SERVICE_ERROR_DHCP_FAILED);
1414 }
1415 #endif
1416
1417 void connman_network_set_ipv4_method(struct connman_network *network,
1418                                         enum connman_ipconfig_method method)
1419 {
1420         struct connman_service *service;
1421         struct connman_ipconfig *ipconfig;
1422
1423         service = connman_service_lookup_from_network(network);
1424         if (!service)
1425                 return;
1426
1427         ipconfig = __connman_service_get_ip4config(service);
1428         if (!ipconfig)
1429                 return;
1430
1431         __connman_ipconfig_set_method(ipconfig, method);
1432 }
1433
1434 void connman_network_set_ipv6_method(struct connman_network *network,
1435                                         enum connman_ipconfig_method method)
1436 {
1437         struct connman_service *service;
1438         struct connman_ipconfig *ipconfig;
1439
1440         service = connman_service_lookup_from_network(network);
1441         if (!service)
1442                 return;
1443
1444         ipconfig = __connman_service_get_ip6config(service);
1445         if (!ipconfig)
1446                 return;
1447
1448         __connman_ipconfig_set_method(ipconfig, method);
1449 }
1450
1451 void connman_network_set_error(struct connman_network *network,
1452                                         enum connman_network_error error)
1453 {
1454         DBG("network %p error %d", network, error);
1455
1456         network->connecting = false;
1457         network->associating = false;
1458
1459         switch (error) {
1460         case CONNMAN_NETWORK_ERROR_UNKNOWN:
1461                 return;
1462         case CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL:
1463                 set_associate_error(network);
1464                 break;
1465         case CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL:
1466                 set_configure_error(network);
1467                 break;
1468         case CONNMAN_NETWORK_ERROR_INVALID_KEY:
1469                 set_invalid_key_error(network);
1470                 break;
1471         case CONNMAN_NETWORK_ERROR_CONNECT_FAIL:
1472                 set_connect_error(network);
1473                 break;
1474 #if defined TIZEN_EXT
1475         case CONNMAN_NETWORK_ERROR_DHCP_FAIL:
1476                 set_dhcp_error(network);
1477                 break;
1478 #endif
1479         }
1480
1481         network_change(network);
1482 }
1483
1484 /**
1485  * connman_network_set_connected:
1486  * @network: network structure
1487  * @connected: connected state
1488  *
1489  * Change connected state of network
1490  */
1491 int connman_network_set_connected(struct connman_network *network,
1492                                                 bool connected)
1493 {
1494         DBG("network %p connected %d/%d connecting %d associating %d",
1495                 network, network->connected, connected, network->connecting,
1496                 network->associating);
1497
1498         if ((network->connecting || network->associating) &&
1499                                                         !connected) {
1500                 connman_network_set_error(network,
1501                                         CONNMAN_NETWORK_ERROR_CONNECT_FAIL);
1502                 if (__connman_network_disconnect(network) == 0)
1503                         return 0;
1504         }
1505
1506         if (network->connected == connected)
1507                 return -EALREADY;
1508
1509         if (!connected)
1510                 set_disconnected(network);
1511         else
1512                 set_connected(network);
1513
1514         return 0;
1515 }
1516
1517 /**
1518  * connman_network_get_connected:
1519  * @network: network structure
1520  *
1521  * Get network connection status
1522  */
1523 bool connman_network_get_connected(struct connman_network *network)
1524 {
1525         return network->connected;
1526 }
1527
1528 /**
1529  * connman_network_get_associating:
1530  * @network: network structure
1531  *
1532  * Get network associating status
1533  */
1534 bool connman_network_get_associating(struct connman_network *network)
1535 {
1536         return network->associating;
1537 }
1538
1539 void connman_network_clear_hidden(void *user_data)
1540 {
1541         if (!user_data)
1542                 return;
1543
1544         DBG("user_data %p", user_data);
1545
1546         /*
1547          * Hidden service does not have a connect timeout so
1548          * we do not need to remove it. We can just return
1549          * error to the caller telling that we could not find
1550          * any network that we could connect to.
1551          */
1552         connman_dbus_reply_pending(user_data, EIO, NULL);
1553 }
1554
1555 int connman_network_connect_hidden(struct connman_network *network,
1556                         char *identity, char *passphrase, void *user_data)
1557 {
1558         int err = 0;
1559         struct connman_service *service;
1560
1561         service = connman_service_lookup_from_network(network);
1562
1563         DBG("network %p service %p user_data %p", network, service, user_data);
1564
1565         if (!service)
1566                 return -EINVAL;
1567
1568         if (identity)
1569                 __connman_service_set_agent_identity(service, identity);
1570
1571         if (passphrase)
1572                 err = __connman_service_set_passphrase(service, passphrase);
1573
1574         if (err == -ENOKEY) {
1575                 __connman_service_indicate_error(service,
1576                                         CONNMAN_SERVICE_ERROR_INVALID_KEY);
1577                 goto out;
1578         } else {
1579                 __connman_service_set_hidden(service);
1580                 __connman_service_set_hidden_data(service, user_data);
1581                 return __connman_service_connect(service,
1582                                         CONNMAN_SERVICE_CONNECT_REASON_USER);
1583         }
1584
1585 out:
1586         __connman_service_return_error(service, -err, user_data);
1587         return err;
1588 }
1589
1590 /**
1591  * __connman_network_connect:
1592  * @network: network structure
1593  *
1594  * Connect network
1595  */
1596 int __connman_network_connect(struct connman_network *network)
1597 {
1598         int err;
1599
1600         DBG("network %p", network);
1601
1602         if (network->connected)
1603                 return -EISCONN;
1604
1605         if (network->connecting || network->associating)
1606                 return -EALREADY;
1607
1608         if (!network->driver)
1609                 return -EUNATCH;
1610
1611         if (!network->driver->connect)
1612                 return -ENOSYS;
1613
1614         if (!network->device)
1615                 return -ENODEV;
1616
1617         network->connecting = true;
1618
1619 #if defined TIZEN_EXT
1620         if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR)
1621 #endif
1622         __connman_device_disconnect(network->device);
1623
1624         err = network->driver->connect(network);
1625         if (err < 0) {
1626                 if (err == -EINPROGRESS) {
1627 #if defined TIZEN_EXT
1628                         if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR)
1629 #endif
1630                         connman_network_set_associating(network, true);
1631                 } else
1632                         network->connecting = false;
1633
1634                 return err;
1635         }
1636
1637         set_connected(network);
1638
1639         return err;
1640 }
1641
1642 /**
1643  * __connman_network_disconnect:
1644  * @network: network structure
1645  *
1646  * Disconnect network
1647  */
1648 int __connman_network_disconnect(struct connman_network *network)
1649 {
1650         int err = 0;
1651
1652         DBG("network %p", network);
1653
1654         if (!network->connected && !network->connecting &&
1655                                                 !network->associating)
1656                 return -ENOTCONN;
1657
1658         if (!network->driver)
1659                 return -EUNATCH;
1660
1661         network->connecting = false;
1662
1663         if (network->driver->disconnect)
1664                 err = network->driver->disconnect(network);
1665
1666         if (err != -EINPROGRESS)
1667                 set_disconnected(network);
1668
1669         return err;
1670 }
1671
1672 int __connman_network_clear_ipconfig(struct connman_network *network,
1673                                         struct connman_ipconfig *ipconfig)
1674 {
1675         struct connman_service *service;
1676         struct connman_ipconfig *ipconfig_ipv4;
1677         enum connman_ipconfig_method method;
1678         enum connman_ipconfig_type type;
1679
1680         service = connman_service_lookup_from_network(network);
1681         if (!service)
1682                 return -EINVAL;
1683
1684         ipconfig_ipv4 = __connman_service_get_ip4config(service);
1685         method = __connman_ipconfig_get_method(ipconfig);
1686         type = __connman_ipconfig_get_config_type(ipconfig);
1687
1688         switch (method) {
1689         case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1690         case CONNMAN_IPCONFIG_METHOD_OFF:
1691         case CONNMAN_IPCONFIG_METHOD_FIXED:
1692                 return -EINVAL;
1693         case CONNMAN_IPCONFIG_METHOD_AUTO:
1694                 release_dhcpv6(network);
1695                 break;
1696         case CONNMAN_IPCONFIG_METHOD_MANUAL:
1697                 __connman_ipconfig_address_remove(ipconfig);
1698                 break;
1699         case CONNMAN_IPCONFIG_METHOD_DHCP:
1700                 __connman_dhcp_stop(ipconfig_ipv4);
1701                 break;
1702         }
1703
1704         if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1705                 __connman_service_ipconfig_indicate_state(service,
1706                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
1707                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1708         else if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1709                 __connman_service_ipconfig_indicate_state(service,
1710                                         CONNMAN_SERVICE_STATE_CONFIGURATION,
1711                                         CONNMAN_IPCONFIG_TYPE_IPV4);
1712
1713         return 0;
1714 }
1715
1716 int __connman_network_enable_ipconfig(struct connman_network *network,
1717                                 struct connman_ipconfig *ipconfig)
1718 {
1719         int r = 0;
1720         enum connman_ipconfig_type type;
1721         enum connman_ipconfig_method method;
1722 #if defined TIZEN_EXT
1723         struct connman_service *service;
1724 #endif
1725
1726         if (!network || !ipconfig)
1727                 return -EINVAL;
1728
1729         type = __connman_ipconfig_get_config_type(ipconfig);
1730
1731         switch (type) {
1732         case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
1733         case CONNMAN_IPCONFIG_TYPE_ALL:
1734                 return -ENOSYS;
1735
1736         case CONNMAN_IPCONFIG_TYPE_IPV6:
1737                 set_configuration(network, type);
1738
1739                 method = __connman_ipconfig_get_method(ipconfig);
1740
1741                 DBG("ipv6 ipconfig method %d", method);
1742
1743                 switch (method) {
1744                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1745                         break;
1746
1747                 case CONNMAN_IPCONFIG_METHOD_OFF:
1748                         __connman_ipconfig_disable_ipv6(ipconfig);
1749                         break;
1750
1751                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1752 #if defined TIZEN_EXT
1753                 service = connman_service_lookup_from_network(network);
1754
1755                 if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR)
1756                         __connman_service_ipconfig_indicate_state(service,
1757                                 CONNMAN_SERVICE_STATE_CONFIGURATION,
1758                                         CONNMAN_IPCONFIG_TYPE_IPV6);
1759 #endif
1760                         autoconf_ipv6_set(network);
1761                         break;
1762
1763                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1764                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1765                         r = manual_ipv6_set(network, ipconfig);
1766                         break;
1767
1768                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1769                         r = -ENOSYS;
1770                         break;
1771                 }
1772
1773                 break;
1774
1775         case CONNMAN_IPCONFIG_TYPE_IPV4:
1776                 set_configuration(network, type);
1777
1778                 method = __connman_ipconfig_get_method(ipconfig);
1779
1780                 DBG("ipv4 ipconfig method %d", method);
1781
1782                 switch (method) {
1783                 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1784                 case CONNMAN_IPCONFIG_METHOD_OFF:
1785                         break;
1786
1787                 case CONNMAN_IPCONFIG_METHOD_AUTO:
1788                         r = -ENOSYS;
1789                         break;
1790
1791                 case CONNMAN_IPCONFIG_METHOD_FIXED:
1792                 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1793                         r = set_connected_manual(network);
1794                         break;
1795
1796                 case CONNMAN_IPCONFIG_METHOD_DHCP:
1797                         r = set_connected_dhcp(network);
1798                         break;
1799                 }
1800
1801                 break;
1802         }
1803
1804         if (r < 0)
1805                 connman_network_set_error(network,
1806                                         CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
1807
1808         return r;
1809 }
1810
1811 int connman_network_set_ipaddress(struct connman_network *network,
1812                                         struct connman_ipaddress *ipaddress)
1813 {
1814         struct connman_service *service;
1815         struct connman_ipconfig *ipconfig = NULL;
1816
1817         DBG("network %p", network);
1818
1819         service = connman_service_lookup_from_network(network);
1820         if (!service)
1821                 return -EINVAL;
1822
1823         ipconfig = __connman_service_get_ipconfig(service, ipaddress->family);
1824         if (!ipconfig)
1825                 return -EINVAL;
1826
1827         __connman_ipconfig_set_local(ipconfig, ipaddress->local);
1828         __connman_ipconfig_set_peer(ipconfig, ipaddress->peer);
1829         __connman_ipconfig_set_broadcast(ipconfig, ipaddress->broadcast);
1830         __connman_ipconfig_set_prefixlen(ipconfig, ipaddress->prefixlen);
1831         __connman_ipconfig_set_gateway(ipconfig, ipaddress->gateway);
1832
1833         return 0;
1834 }
1835
1836 #if defined TIZEN_EXT
1837 /*
1838  * Description: Network client requires additional wifi specific info
1839  */
1840 int connman_network_set_bssid(struct connman_network *network,
1841                                 const unsigned char *bssid)
1842 {
1843         int i = 0;
1844
1845         if (bssid == NULL)
1846                 return -EINVAL;
1847
1848         DBG("network %p bssid %02x:%02x:%02x:%02x:%02x:%02x", network,
1849                         bssid[0], bssid[1], bssid[2],
1850                         bssid[3], bssid[4], bssid[5]);
1851
1852         for (;i < WIFI_BSSID_LEN_MAX;i++)
1853                 network->wifi.bssid[i] = bssid[i];
1854
1855         return 0;
1856 }
1857
1858 unsigned char *connman_network_get_bssid(struct connman_network *network)
1859 {
1860         return (unsigned char *)network->wifi.bssid;
1861 }
1862
1863 int connman_network_set_maxrate(struct connman_network *network,
1864                                 unsigned int maxrate)
1865 {
1866 #if !defined TIZEN_EXT
1867         DBG("network %p maxrate %d", network, maxrate);
1868 #endif
1869
1870         network->wifi.maxrate = maxrate;
1871
1872         return 0;
1873 }
1874
1875 unsigned int connman_network_get_maxrate(struct connman_network *network)
1876 {
1877         return network->wifi.maxrate;
1878 }
1879
1880 int connman_network_set_enc_mode(struct connman_network *network,
1881                                 const char *encryption_mode)
1882 {
1883         if (encryption_mode == NULL)
1884                 return -EINVAL;
1885
1886         DBG("network %p encryption mode %s", network, encryption_mode);
1887
1888         g_strlcpy(network->wifi.encryption_mode, encryption_mode,
1889                                         WIFI_ENCYPTION_MODE_LEN_MAX);
1890
1891         return 0;
1892 }
1893
1894 const char *connman_network_get_enc_mode(struct connman_network *network)
1895 {
1896         return (const char *)network->wifi.encryption_mode;
1897 }
1898
1899 int connman_network_set_rsn_selected(struct connman_network *network,
1900                                 bool rsn_selected)
1901 {
1902         network->wifi.rsn_selected = rsn_selected;
1903
1904         return 0;
1905 }
1906
1907 int connman_network_set_proxy(struct connman_network *network,
1908                                 const char *proxies)
1909 {
1910         struct connman_service *service;
1911
1912         DBG("network %p proxies %s", network, proxies);
1913
1914         service = connman_service_lookup_from_network(network);
1915         if (service == NULL)
1916                 return -EINVAL;
1917
1918         __connman_service_set_proxy(service, proxies);
1919
1920         connman_service_set_proxy_method(service,
1921                                 CONNMAN_SERVICE_PROXY_METHOD_MANUAL);
1922
1923         return 0;
1924 }
1925
1926 int connman_network_set_is_hs20AP(struct connman_network *network,
1927                                 unsigned int isHS20AP)
1928 {
1929         if (!network)
1930                 return 0;
1931
1932         network->wifi.isHS20AP = isHS20AP;
1933
1934         return 0;
1935 }
1936
1937 unsigned int connman_network_get_is_hs20AP(struct connman_network *network)
1938 {
1939         if (!network)
1940                 return 0;
1941
1942         return network->wifi.isHS20AP;
1943 }
1944 #endif
1945
1946 int connman_network_set_nameservers(struct connman_network *network,
1947                                 const char *nameservers)
1948 {
1949         struct connman_service *service;
1950         char **nameservers_array;
1951         int i;
1952
1953         DBG("network %p nameservers %s", network, nameservers);
1954
1955         service = connman_service_lookup_from_network(network);
1956         if (!service)
1957                 return -EINVAL;
1958
1959         __connman_service_nameserver_clear(service);
1960
1961         if (!nameservers)
1962                 return 0;
1963
1964         nameservers_array = g_strsplit(nameservers, " ", 0);
1965
1966         for (i = 0; nameservers_array[i]; i++) {
1967                 __connman_service_nameserver_append(service,
1968                                                 nameservers_array[i], false);
1969         }
1970
1971         g_strfreev(nameservers_array);
1972
1973         return 0;
1974 }
1975
1976 int connman_network_set_domain(struct connman_network *network,
1977                                 const char *domain)
1978 {
1979         struct connman_service *service;
1980
1981         DBG("network %p domain %s", network, domain);
1982
1983         service = connman_service_lookup_from_network(network);
1984         if (!service)
1985                 return -EINVAL;
1986
1987         __connman_service_set_domainname(service, domain);
1988
1989         return 0;
1990 }
1991
1992 /**
1993  * connman_network_set_name:
1994  * @network: network structure
1995  * @name: name value
1996  *
1997  * Set display name value for network
1998  */
1999 int connman_network_set_name(struct connman_network *network,
2000                                                         const char *name)
2001 {
2002         DBG("network %p name %s", network, name);
2003
2004         g_free(network->name);
2005         network->name = g_strdup(name);
2006
2007         return 0;
2008 }
2009
2010 /**
2011  * connman_network_set_strength:
2012  * @network: network structure
2013  * @strength: strength value
2014  *
2015  * Set signal strength value for network
2016  */
2017
2018 int connman_network_set_strength(struct connman_network *network,
2019                                                 uint8_t strength)
2020 {
2021 #if !defined TIZEN_EXT
2022         DBG("network %p strengh %d", network, strength);
2023 #endif
2024
2025         network->strength = strength;
2026
2027         return 0;
2028 }
2029
2030 uint8_t connman_network_get_strength(struct connman_network *network)
2031 {
2032         return network->strength;
2033 }
2034
2035 int connman_network_set_frequency(struct connman_network *network,
2036                                                 uint16_t frequency)
2037 {
2038 #if !defined TIZEN_EXT
2039         DBG("network %p frequency %d", network, frequency);
2040 #endif
2041
2042         network->frequency = frequency;
2043
2044         return 0;
2045 }
2046
2047 uint16_t connman_network_get_frequency(struct connman_network *network)
2048 {
2049         return network->frequency;
2050 }
2051
2052 int connman_network_set_wifi_channel(struct connman_network *network,
2053                                                 uint16_t channel)
2054 {
2055         DBG("network %p wifi channel %d", network, channel);
2056
2057         network->wifi.channel = channel;
2058
2059         return 0;
2060 }
2061
2062 uint16_t connman_network_get_wifi_channel(struct connman_network *network)
2063 {
2064         return network->wifi.channel;
2065 }
2066
2067 /**
2068  * connman_network_set_string:
2069  * @network: network structure
2070  * @key: unique identifier
2071  * @value: string value
2072  *
2073  * Set string value for specific key
2074  */
2075 int connman_network_set_string(struct connman_network *network,
2076                                         const char *key, const char *value)
2077 {
2078 #if !defined TIZEN_EXT
2079         DBG("network %p key %s value %s", network, key, value);
2080 #endif
2081
2082         if (g_strcmp0(key, "Name") == 0)
2083                 return connman_network_set_name(network, value);
2084
2085         if (g_str_equal(key, "Path")) {
2086                 g_free(network->path);
2087                 network->path = g_strdup(value);
2088         } else if (g_str_equal(key, "Node")) {
2089                 g_free(network->node);
2090                 network->node = g_strdup(value);
2091         } else if (g_str_equal(key, "WiFi.Mode")) {
2092                 g_free(network->wifi.mode);
2093                 network->wifi.mode = g_strdup(value);
2094         } else if (g_str_equal(key, "WiFi.Security")) {
2095                 g_free(network->wifi.security);
2096                 network->wifi.security = g_strdup(value);
2097         } else if (g_str_equal(key, "WiFi.Passphrase")) {
2098                 g_free(network->wifi.passphrase);
2099                 network->wifi.passphrase = g_strdup(value);
2100         } else if (g_str_equal(key, "WiFi.EAP")) {
2101                 g_free(network->wifi.eap);
2102                 network->wifi.eap = g_strdup(value);
2103         } else if (g_str_equal(key, "WiFi.Identity")) {
2104                 g_free(network->wifi.identity);
2105                 network->wifi.identity = g_strdup(value);
2106         } else if (g_str_equal(key, "WiFi.AgentIdentity")) {
2107                 g_free(network->wifi.agent_identity);
2108                 network->wifi.agent_identity = g_strdup(value);
2109         } else if (g_str_equal(key, "WiFi.CACertFile")) {
2110                 g_free(network->wifi.ca_cert_path);
2111                 network->wifi.ca_cert_path = g_strdup(value);
2112         } else if (g_str_equal(key, "WiFi.ClientCertFile")) {
2113                 g_free(network->wifi.client_cert_path);
2114                 network->wifi.client_cert_path = g_strdup(value);
2115         } else if (g_str_equal(key, "WiFi.PrivateKeyFile")) {
2116                 g_free(network->wifi.private_key_path);
2117                 network->wifi.private_key_path = g_strdup(value);
2118         } else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase")) {
2119                 g_free(network->wifi.private_key_passphrase);
2120                 network->wifi.private_key_passphrase = g_strdup(value);
2121         } else if (g_str_equal(key, "WiFi.Phase2")) {
2122                 g_free(network->wifi.phase2_auth);
2123                 network->wifi.phase2_auth = g_strdup(value);
2124         } else if (g_str_equal(key, "WiFi.PinWPS")) {
2125                 g_free(network->wifi.pin_wps);
2126                 network->wifi.pin_wps = g_strdup(value);
2127         } else {
2128                 return -EINVAL;
2129         }
2130
2131         return 0;
2132 }
2133
2134 /**
2135  * connman_network_get_string:
2136  * @network: network structure
2137  * @key: unique identifier
2138  *
2139  * Get string value for specific key
2140  */
2141 const char *connman_network_get_string(struct connman_network *network,
2142                                                         const char *key)
2143 {
2144 #if !defined TIZEN_EXT
2145         DBG("network %p key %s", network, key);
2146 #endif
2147
2148         if (g_str_equal(key, "Path"))
2149                 return network->path;
2150         else if (g_str_equal(key, "Name"))
2151                 return network->name;
2152         else if (g_str_equal(key, "Node"))
2153                 return network->node;
2154         else if (g_str_equal(key, "WiFi.Mode"))
2155                 return network->wifi.mode;
2156         else if (g_str_equal(key, "WiFi.Security"))
2157 #if defined TIZEN_EXT
2158                 if (network->wifi.rsn_selected != true ||
2159                     g_str_equal(network->wifi.security, "ieee8021x"))
2160                         return network->wifi.security;
2161                 else
2162                         return "rsn";
2163 #else
2164                 return network->wifi.security;
2165 #endif
2166         else if (g_str_equal(key, "WiFi.Passphrase"))
2167                 return network->wifi.passphrase;
2168         else if (g_str_equal(key, "WiFi.EAP"))
2169                 return network->wifi.eap;
2170         else if (g_str_equal(key, "WiFi.Identity"))
2171                 return network->wifi.identity;
2172         else if (g_str_equal(key, "WiFi.AgentIdentity"))
2173                 return network->wifi.agent_identity;
2174         else if (g_str_equal(key, "WiFi.CACertFile"))
2175                 return network->wifi.ca_cert_path;
2176         else if (g_str_equal(key, "WiFi.ClientCertFile"))
2177                 return network->wifi.client_cert_path;
2178         else if (g_str_equal(key, "WiFi.PrivateKeyFile"))
2179                 return network->wifi.private_key_path;
2180         else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase"))
2181                 return network->wifi.private_key_passphrase;
2182         else if (g_str_equal(key, "WiFi.Phase2"))
2183                 return network->wifi.phase2_auth;
2184         else if (g_str_equal(key, "WiFi.PinWPS"))
2185                 return network->wifi.pin_wps;
2186
2187         return NULL;
2188 }
2189
2190 /**
2191  * connman_network_set_bool:
2192  * @network: network structure
2193  * @key: unique identifier
2194  * @value: boolean value
2195  *
2196  * Set boolean value for specific key
2197  */
2198 int connman_network_set_bool(struct connman_network *network,
2199                                         const char *key, bool value)
2200 {
2201 #if !defined TIZEN_EXT
2202         DBG("network %p key %s value %d", network, key, value);
2203 #endif
2204
2205         if (g_strcmp0(key, "Roaming") == 0)
2206                 network->roaming = value;
2207         else if (g_strcmp0(key, "WiFi.WPS") == 0)
2208                 network->wifi.wps = value;
2209         else if (g_strcmp0(key, "WiFi.UseWPS") == 0)
2210                 network->wifi.use_wps = value;
2211 #if defined TIZEN_EXT
2212         else if (g_strcmp0(key, "DefaultInternet") == 0)
2213                 network->default_internet = value;
2214 #endif
2215
2216         return -EINVAL;
2217 }
2218
2219 /**
2220  * connman_network_get_bool:
2221  * @network: network structure
2222  * @key: unique identifier
2223  *
2224  * Get boolean value for specific key
2225  */
2226 bool connman_network_get_bool(struct connman_network *network,
2227                                                         const char *key)
2228 {
2229 #if !defined TIZEN_EXT
2230         DBG("network %p key %s", network, key);
2231 #endif
2232
2233         if (g_str_equal(key, "Roaming"))
2234                 return network->roaming;
2235         else if (g_str_equal(key, "WiFi.WPS"))
2236                 return network->wifi.wps;
2237         else if (g_str_equal(key, "WiFi.UseWPS"))
2238                 return network->wifi.use_wps;
2239 #if defined TIZEN_EXT
2240         else if (g_str_equal(key, "DefaultInternet"))
2241                 return network->default_internet;
2242 #endif
2243
2244         return false;
2245 }
2246
2247 /**
2248  * connman_network_set_blob:
2249  * @network: network structure
2250  * @key: unique identifier
2251  * @data: blob data
2252  * @size: blob size
2253  *
2254  * Set binary blob value for specific key
2255  */
2256 int connman_network_set_blob(struct connman_network *network,
2257                         const char *key, const void *data, unsigned int size)
2258 {
2259 #if !defined TIZEN_EXT
2260         DBG("network %p key %s size %d", network, key, size);
2261 #endif
2262
2263         if (g_str_equal(key, "WiFi.SSID")) {
2264                 g_free(network->wifi.ssid);
2265                 network->wifi.ssid = g_try_malloc(size);
2266                 if (network->wifi.ssid) {
2267                         memcpy(network->wifi.ssid, data, size);
2268                         network->wifi.ssid_len = size;
2269                 } else
2270                         network->wifi.ssid_len = 0;
2271         } else {
2272                 return -EINVAL;
2273         }
2274
2275         return 0;
2276 }
2277
2278 /**
2279  * connman_network_get_blob:
2280  * @network: network structure
2281  * @key: unique identifier
2282  * @size: pointer to blob size
2283  *
2284  * Get binary blob value for specific key
2285  */
2286 const void *connman_network_get_blob(struct connman_network *network,
2287                                         const char *key, unsigned int *size)
2288 {
2289         DBG("network %p key %s", network, key);
2290
2291         if (g_str_equal(key, "WiFi.SSID")) {
2292                 if (size)
2293                         *size = network->wifi.ssid_len;
2294                 return network->wifi.ssid;
2295         }
2296
2297         return NULL;
2298 }
2299
2300 void __connman_network_set_device(struct connman_network *network,
2301                                         struct connman_device *device)
2302 {
2303         if (network->device == device)
2304                 return;
2305
2306         if (network->device)
2307                 network_remove(network);
2308
2309         network->device = device;
2310
2311         if (network->device)
2312                 network_probe(network);
2313 }
2314
2315 /**
2316  * connman_network_get_device:
2317  * @network: network structure
2318  *
2319  * Get parent device of network
2320  */
2321 struct connman_device *connman_network_get_device(struct connman_network *network)
2322 {
2323         return network->device;
2324 }
2325
2326 /**
2327  * connman_network_get_data:
2328  * @network: network structure
2329  *
2330  * Get private network data pointer
2331  */
2332 void *connman_network_get_data(struct connman_network *network)
2333 {
2334         return network->driver_data;
2335 }
2336
2337 /**
2338  * connman_network_set_data:
2339  * @network: network structure
2340  * @data: data pointer
2341  *
2342  * Set private network data pointer
2343  */
2344 void connman_network_set_data(struct connman_network *network, void *data)
2345 {
2346         network->driver_data = data;
2347 }
2348
2349 void connman_network_update(struct connman_network *network)
2350 {
2351         switch (network->type) {
2352         case CONNMAN_NETWORK_TYPE_UNKNOWN:
2353         case CONNMAN_NETWORK_TYPE_VENDOR:
2354                 return;
2355         case CONNMAN_NETWORK_TYPE_ETHERNET:
2356         case CONNMAN_NETWORK_TYPE_GADGET:
2357         case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
2358         case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
2359         case CONNMAN_NETWORK_TYPE_CELLULAR:
2360         case CONNMAN_NETWORK_TYPE_WIFI:
2361                 break;
2362         }
2363
2364         if (network->group)
2365                 __connman_service_update_from_network(network);
2366 }
2367
2368 int __connman_network_init(void)
2369 {
2370         DBG("");
2371
2372         return 0;
2373 }
2374
2375 void __connman_network_cleanup(void)
2376 {
2377         DBG("");
2378 }