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