ce5421c3e408c3d44f5896a5b0796db10c5e3697
[platform/core/api/connection.git] / src / connection.c
1 /*
2  * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <glib.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <vconf/vconf.h>
21
22 #include "net_connection_private.h"
23
24 static __thread GSList *conn_handle_list = NULL;
25
26 static int __connection_convert_net_state(int status)
27 {
28         switch (status) {
29         case VCONFKEY_NETWORK_CELLULAR:
30                 return CONNECTION_TYPE_CELLULAR;
31         case VCONFKEY_NETWORK_WIFI:
32                 return CONNECTION_TYPE_WIFI;
33         case VCONFKEY_NETWORK_ETHERNET:
34                 return CONNECTION_TYPE_ETHERNET;
35         case VCONFKEY_NETWORK_BLUETOOTH:
36                 return CONNECTION_TYPE_BT;
37         default:
38                 return CONNECTION_TYPE_DISCONNECTED;
39         }
40 }
41
42 static int __connection_convert_cellular_state(int status)
43 {
44         switch (status) {
45         case VCONFKEY_NETWORK_CELLULAR_ON:
46                 return CONNECTION_CELLULAR_STATE_AVAILABLE;
47         case VCONFKEY_NETWORK_CELLULAR_3G_OPTION_OFF:
48                 return CONNECTION_CELLULAR_STATE_CALL_ONLY_AVAILABLE;
49         case VCONFKEY_NETWORK_CELLULAR_ROAMING_OFF:
50                 return CONNECTION_CELLULAR_STATE_ROAMING_OFF;
51         case VCONFKEY_NETWORK_CELLULAR_FLIGHT_MODE:
52                 return CONNECTION_CELLULAR_STATE_FLIGHT_MODE;
53         default:
54                 return CONNECTION_CELLULAR_STATE_OUT_OF_SERVICE;
55         }
56 }
57
58 static bool __connection_check_handle_validity(connection_h connection)
59 {
60         bool ret = false;
61
62         if (connection == NULL)
63                 return false;
64
65         if (g_slist_find(conn_handle_list, connection) != NULL)
66                 ret = true;
67
68         return ret;
69 }
70
71 static connection_type_changed_cb
72 __connection_get_type_changed_callback(connection_handle_s *local_handle)
73 {
74         return local_handle->type_changed_callback;
75 }
76
77 static void *__connection_get_type_changed_userdata(
78                                                         connection_handle_s *local_handle)
79 {
80         return local_handle->type_changed_user_data;
81 }
82
83 static gboolean __connection_cb_type_changed_cb_idle(gpointer user_data)
84 {
85         int state, status;
86         void *data;
87         connection_type_changed_cb callback;
88         connection_handle_s *local_handle = (connection_handle_s *)user_data;
89
90         if (__connection_check_handle_validity((connection_h)local_handle) != true)
91                 return FALSE;
92
93         if (vconf_get_int(VCONFKEY_NETWORK_STATUS, &status) != 0)
94                 return FALSE;
95
96         state = __connection_convert_net_state(status);
97
98         callback = __connection_get_type_changed_callback(local_handle);
99         data = __connection_get_type_changed_userdata(local_handle);
100         if (callback)
101                 callback(state, data);
102
103         return FALSE;
104 }
105
106 static void __connection_cb_type_change_cb(keynode_t *node, void *user_data)
107 {
108         GSList *list;
109         connection_h handle;
110
111         if (_connection_is_created() != true) {
112                 CONNECTION_LOG(CONNECTION_ERROR, "Application is not registered"
113                                 "If multi-threaded, thread integrity be broken.");
114                 return;
115         }
116
117         for (list = conn_handle_list; list; list = list->next) {
118                 handle = (connection_h)list->data;
119                 _connection_callback_add(__connection_cb_type_changed_cb_idle, (gpointer)handle);
120         }
121 }
122
123 static void __connection_cb_ethernet_cable_state_changed_cb(connection_ethernet_cable_state_e state)
124 {
125         CONNECTION_LOG(CONNECTION_INFO, "Ethernet Cable state Indication");
126
127         GSList *list;
128
129         for (list = conn_handle_list; list; list = list->next) {
130                 connection_handle_s *local_handle = (connection_handle_s *)list->data;
131                 if (local_handle->ethernet_cable_state_changed_callback)
132                         local_handle->ethernet_cable_state_changed_callback(state,
133                                         local_handle->ethernet_cable_state_changed_user_data);
134         }
135 }
136
137 static int __connection_get_ethernet_cable_state_changed_callback_count(void)
138 {
139         GSList *list;
140         int count = 0;
141
142         for (list = conn_handle_list; list; list = list->next) {
143                 connection_handle_s *local_handle = (connection_handle_s *)list->data;
144                 if (local_handle->ethernet_cable_state_changed_callback) count++;
145         }
146
147         return count;
148 }
149
150 static int __connection_set_type_changed_callback(connection_h connection,
151                                                         void *callback, void *user_data)
152 {
153         static __thread gint refcount = 0;
154         connection_handle_s *local_handle;
155
156         local_handle = (connection_handle_s *)connection;
157
158         if (callback) {
159                 if (refcount == 0)
160                         vconf_notify_key_changed(VCONFKEY_NETWORK_STATUS,
161                                         __connection_cb_type_change_cb, NULL);
162
163                 refcount++;
164                 CONNECTION_LOG(CONNECTION_INFO, "Successfully registered(%d)", refcount);
165         } else {
166                 if (refcount > 0 &&
167                                 __connection_get_type_changed_callback(local_handle) != NULL) {
168                         if (--refcount == 0) {
169                                 if (vconf_ignore_key_changed(VCONFKEY_NETWORK_STATUS,
170                                                 __connection_cb_type_change_cb) < 0) {
171                                         CONNECTION_LOG(CONNECTION_ERROR,
172                                                         "Error to de-register vconf callback(%d)", refcount);
173                                 } else {
174                                         CONNECTION_LOG(CONNECTION_INFO,
175                                                         "Successfully de-registered(%d)", refcount);
176                                 }
177                         }
178                 }
179         }
180
181         local_handle->type_changed_user_data = user_data;
182         local_handle->type_changed_callback = callback;
183
184         return CONNECTION_ERROR_NONE;
185 }
186
187 static connection_address_changed_cb
188 __connection_get_ip_changed_callback(connection_handle_s *local_handle)
189 {
190         return local_handle->ip_changed_callback;
191 }
192
193 static void *__connection_get_ip_changed_userdata(
194                                                         connection_handle_s *local_handle)
195 {
196         return local_handle->ip_changed_user_data;
197 }
198
199 static gboolean __connection_cb_ip_changed_cb_idle(gpointer user_data)
200 {
201         char *ip_addr;
202         void *data;
203         connection_address_changed_cb callback;
204         connection_handle_s *local_handle = (connection_handle_s *)user_data;
205
206         if (__connection_check_handle_validity((connection_h)local_handle) != true)
207                 return FALSE;
208
209         ip_addr = vconf_get_str(VCONFKEY_NETWORK_IP);
210
211         callback = __connection_get_ip_changed_callback(local_handle);
212         data = __connection_get_ip_changed_userdata(local_handle);
213         /* TODO: IPv6 should be supported */
214         if (callback)
215                 callback(ip_addr, NULL, data);
216
217         return FALSE;
218 }
219
220 static void __connection_cb_ip_change_cb(keynode_t *node, void *user_data)
221 {
222         GSList *list;
223         connection_h handle;
224
225         if (_connection_is_created() != true) {
226                 CONNECTION_LOG(CONNECTION_ERROR, "Application is not registered"
227                                 "If multi-threaded, thread integrity be broken.");
228                 return;
229         }
230
231         for (list = conn_handle_list; list; list = list->next) {
232                 handle = (connection_h)list->data;
233                 _connection_callback_add(__connection_cb_ip_changed_cb_idle, (gpointer)handle);
234         }
235 }
236
237 static int __connection_set_ip_changed_callback(connection_h connection,
238                                                         void *callback, void *user_data)
239 {
240         static __thread gint refcount = 0;
241         connection_handle_s *local_handle;
242
243         local_handle = (connection_handle_s *)connection;
244
245         if (callback) {
246                 if (refcount == 0)
247                         vconf_notify_key_changed(VCONFKEY_NETWORK_IP,
248                                         __connection_cb_ip_change_cb, NULL);
249
250                 refcount++;
251                 CONNECTION_LOG(CONNECTION_INFO, "Successfully registered(%d)", refcount);
252         } else {
253                 if (refcount > 0 &&
254                                 __connection_get_ip_changed_callback(local_handle) != NULL) {
255                         if (--refcount == 0) {
256                                 if (vconf_ignore_key_changed(VCONFKEY_NETWORK_IP,
257                                                 __connection_cb_ip_change_cb) < 0) {
258                                         CONNECTION_LOG(CONNECTION_ERROR,
259                                                         "Error to de-register vconf callback(%d)", refcount);
260                                 } else {
261                                         CONNECTION_LOG(CONNECTION_INFO,
262                                                         "Successfully de-registered(%d)", refcount);
263                                 }
264                         }
265                 }
266         }
267
268         local_handle->ip_changed_user_data = user_data;
269         local_handle->ip_changed_callback = callback;
270
271         return CONNECTION_ERROR_NONE;
272 }
273
274 static connection_address_changed_cb
275 __connection_get_proxy_changed_callback(connection_handle_s *local_handle)
276 {
277         return local_handle->proxy_changed_callback;
278 }
279
280 static void *__connection_get_proxy_changed_userdata(
281                                                         connection_handle_s *local_handle)
282 {
283         return local_handle->proxy_changed_user_data;
284 }
285
286 static gboolean __connection_cb_proxy_changed_cb_idle(gpointer user_data)
287 {
288         char *proxy;
289         void *data;
290         connection_address_changed_cb callback;
291         connection_handle_s *local_handle = (connection_handle_s *)user_data;
292
293         if (__connection_check_handle_validity((connection_h)local_handle) != true)
294                 return FALSE;
295
296         proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY);
297
298         callback = __connection_get_proxy_changed_callback(local_handle);
299         data = __connection_get_proxy_changed_userdata(local_handle);
300         /* TODO: IPv6 should be supported */
301         if (callback)
302                 callback(proxy, NULL, data);
303
304         return FALSE;
305 }
306
307 static void __connection_cb_proxy_change_cb(keynode_t *node, void *user_data)
308 {
309         GSList *list;
310         connection_h handle;
311
312         if (_connection_is_created() != true) {
313                 CONNECTION_LOG(CONNECTION_ERROR, "Application is not registered"
314                                 "If multi-threaded, thread integrity be broken.");
315                 return;
316         }
317
318         for (list = conn_handle_list; list; list = list->next) {
319                 handle = (connection_h)list->data;
320                 _connection_callback_add(__connection_cb_proxy_changed_cb_idle, (gpointer)handle);
321         }
322 }
323
324 static int __connection_set_proxy_changed_callback(connection_h connection,
325                                                         void *callback, void *user_data)
326 {
327         static __thread gint refcount = 0;
328         connection_handle_s *local_handle;
329
330         local_handle = (connection_handle_s *)connection;
331
332         if (callback) {
333                 if (refcount == 0)
334                         vconf_notify_key_changed(VCONFKEY_NETWORK_PROXY,
335                                         __connection_cb_proxy_change_cb, NULL);
336
337                 refcount++;
338                 CONNECTION_LOG(CONNECTION_INFO, "Successfully registered(%d)", refcount);
339         } else {
340                 if (refcount > 0 &&
341                                 __connection_get_proxy_changed_callback(local_handle) != NULL) {
342                         if (--refcount == 0) {
343                                 if (vconf_ignore_key_changed(VCONFKEY_NETWORK_PROXY,
344                                                 __connection_cb_proxy_change_cb) < 0) {
345                                         CONNECTION_LOG(CONNECTION_ERROR,
346                                                         "Error to de-register vconf callback(%d)", refcount);
347                                 } else {
348                                         CONNECTION_LOG(CONNECTION_INFO,
349                                                         "Successfully de-registered(%d)", refcount);
350                                 }
351                         }
352                 }
353         }
354
355         local_handle->proxy_changed_user_data = user_data;
356         local_handle->proxy_changed_callback = callback;
357
358         return CONNECTION_ERROR_NONE;
359 }
360
361 static int __connection_set_ethernet_cable_state_changed_cb(connection_h connection,
362                 connection_ethernet_cable_state_chaged_cb callback, void *user_data)
363 {
364         connection_handle_s *local_handle = (connection_handle_s *)connection;
365
366         if (callback) {
367                 if (__connection_get_ethernet_cable_state_changed_callback_count() == 0)
368                         _connection_libnet_set_ethernet_cable_state_changed_cb(
369                                         __connection_cb_ethernet_cable_state_changed_cb);
370
371         } else {
372                 if (__connection_get_ethernet_cable_state_changed_callback_count() == 1)
373                         _connection_libnet_set_ethernet_cable_state_changed_cb(NULL);
374         }
375
376         local_handle->ethernet_cable_state_changed_callback = callback;
377         local_handle->ethernet_cable_state_changed_user_data = user_data;
378         return CONNECTION_ERROR_NONE;
379 }
380
381 static int __connection_get_handle_count(void)
382 {
383         return ((int)g_slist_length(conn_handle_list));
384 }
385
386 /* Connection Manager ********************************************************/
387 EXPORT_API int connection_create(connection_h *connection)
388 {
389         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
390
391         if (connection == NULL || __connection_check_handle_validity(*connection)) {
392                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
393                 return CONNECTION_ERROR_INVALID_PARAMETER;
394         }
395
396         int rv = _connection_libnet_init();
397         if (rv == NET_ERR_ACCESS_DENIED) {
398                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
399                 return CONNECTION_ERROR_PERMISSION_DENIED;
400         }
401         else if (rv != NET_ERR_NONE) {
402                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to create connection[%d]", rv);
403                 return CONNECTION_ERROR_OPERATION_FAILED;
404         }
405
406         *connection = g_try_malloc0(sizeof(connection_handle_s));
407         if (*connection != NULL)
408                 CONNECTION_LOG(CONNECTION_INFO, "New handle created[%p]", *connection);
409         else
410                 return CONNECTION_ERROR_OUT_OF_MEMORY;
411
412         conn_handle_list = g_slist_prepend(conn_handle_list, *connection);
413
414         return CONNECTION_ERROR_NONE;
415 }
416
417 EXPORT_API int connection_destroy(connection_h connection)
418 {
419         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
420
421         if (!(__connection_check_handle_validity(connection))) {
422                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
423                 return CONNECTION_ERROR_INVALID_PARAMETER;
424         }
425
426         CONNECTION_LOG(CONNECTION_INFO, "Destroy handle: %p", connection);
427
428         __connection_set_type_changed_callback(connection, NULL, NULL);
429         __connection_set_ip_changed_callback(connection, NULL, NULL);
430         __connection_set_proxy_changed_callback(connection, NULL, NULL);
431         __connection_set_ethernet_cable_state_changed_cb(connection, NULL, NULL);
432
433         conn_handle_list = g_slist_remove(conn_handle_list, connection);
434
435         g_free(connection);
436         connection = NULL;
437
438         if (__connection_get_handle_count() == 0) {
439                 _connection_libnet_deinit();
440                 _connection_callback_cleanup();
441         }
442
443         return CONNECTION_ERROR_NONE;
444 }
445
446 EXPORT_API int connection_get_type(connection_h connection, connection_type_e* type)
447 {
448         int rv = 0;
449         int status = 0;
450
451         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
452
453         if (type == NULL || !(__connection_check_handle_validity(connection))) {
454                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
455                 return CONNECTION_ERROR_INVALID_PARAMETER;
456         }
457
458         rv = vconf_get_int(VCONFKEY_NETWORK_STATUS, &status);
459         if (rv != VCONF_OK) {
460                 CONNECTION_LOG(CONNECTION_ERROR, "vconf_get_int Failed = %d", status);
461                 return CONNECTION_ERROR_OPERATION_FAILED;
462         }
463
464         CONNECTION_LOG(CONNECTION_INFO, "Connected Network = %d", status);
465
466         *type = __connection_convert_net_state(status);
467
468         return CONNECTION_ERROR_NONE;
469 }
470
471 EXPORT_API int connection_get_ip_address(connection_h connection,
472                                 connection_address_family_e address_family, char** ip_address)
473 {
474         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
475
476         if (ip_address == NULL || !(__connection_check_handle_validity(connection))) {
477                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
478                 return CONNECTION_ERROR_INVALID_PARAMETER;
479         }
480
481         switch (address_family) {
482         case CONNECTION_ADDRESS_FAMILY_IPV4:
483         case CONNECTION_ADDRESS_FAMILY_IPV6:
484                 *ip_address = vconf_get_str(VCONFKEY_NETWORK_IP);
485                 break;
486         default:
487                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
488                 return CONNECTION_ERROR_INVALID_PARAMETER;
489         }
490
491         if (*ip_address == NULL) {
492                 CONNECTION_LOG(CONNECTION_ERROR, "vconf_get_str Failed");
493                 return CONNECTION_ERROR_OPERATION_FAILED;
494         }
495
496         return CONNECTION_ERROR_NONE;
497 }
498
499 EXPORT_API int connection_get_proxy(connection_h connection,
500                                 connection_address_family_e address_family, char** proxy)
501 {
502         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
503
504         if (proxy == NULL || !(__connection_check_handle_validity(connection))) {
505                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
506                 return CONNECTION_ERROR_INVALID_PARAMETER;
507         }
508
509         switch (address_family) {
510         case CONNECTION_ADDRESS_FAMILY_IPV4:
511         case CONNECTION_ADDRESS_FAMILY_IPV6:
512                 *proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY);
513                 break;
514         default:
515                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
516                 return CONNECTION_ERROR_INVALID_PARAMETER;
517         }
518
519         if (*proxy == NULL) {
520                 CONNECTION_LOG(CONNECTION_ERROR, "vconf_get_str Failed");
521                 return CONNECTION_ERROR_OPERATION_FAILED;
522         }
523
524         return CONNECTION_ERROR_NONE;
525 }
526
527 EXPORT_API int connection_get_mac_address(connection_h connection, connection_type_e type, char** mac_addr)
528 {
529         FILE *fp;
530         char buf[CONNECTION_MAC_INFO_LENGTH + 1];
531
532         CHECK_FEATURE_SUPPORTED(WIFI_FEATURE, ETHERNET_FEATURE);
533
534         if(type == CONNECTION_TYPE_WIFI)
535                 CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
536         else if(type == CONNECTION_TYPE_ETHERNET)
537                 CHECK_FEATURE_SUPPORTED(ETHERNET_FEATURE);
538
539         if (mac_addr == NULL || !(__connection_check_handle_validity(connection))) {
540                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
541                 return CONNECTION_ERROR_INVALID_PARAMETER;
542         }
543
544         switch (type) {
545         case CONNECTION_TYPE_WIFI:
546                 fp = fopen(WIFI_MAC_INFO_FILE, "r");
547                 if (fp == NULL) {
548                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to open file %s", WIFI_MAC_INFO_FILE);
549                         return CONNECTION_ERROR_OUT_OF_MEMORY;
550                 }
551
552                 if (fgets(buf, sizeof(buf), fp) == NULL) {
553                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to get MAC info from %s", WIFI_MAC_INFO_FILE);
554                         fclose(fp);
555                         return CONNECTION_ERROR_OPERATION_FAILED;
556                 }
557
558                 CONNECTION_LOG(CONNECTION_INFO, "%s : %s", WIFI_MAC_INFO_FILE, buf);
559
560                 *mac_addr = (char *)malloc(CONNECTION_MAC_INFO_LENGTH + 1);
561                 if (*mac_addr == NULL) {
562                         CONNECTION_LOG(CONNECTION_ERROR, "malloc() failed");
563                         fclose(fp);
564                         return CONNECTION_ERROR_OUT_OF_MEMORY;
565                 }
566                 g_strlcpy(*mac_addr, buf, CONNECTION_MAC_INFO_LENGTH + 1);
567                 fclose(fp);
568                 break;
569         case CONNECTION_TYPE_ETHERNET:
570                 fp = fopen(ETHERNET_MAC_INFO_FILE, "r");
571                 if (fp == NULL) {
572                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to open file %s", ETHERNET_MAC_INFO_FILE);
573                         return CONNECTION_ERROR_OUT_OF_MEMORY;
574                 }
575
576                 if (fgets(buf, sizeof(buf), fp) == NULL) {
577                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to get MAC info from %s", ETHERNET_MAC_INFO_FILE);
578                         fclose(fp);
579                         return CONNECTION_ERROR_OPERATION_FAILED;
580                 }
581
582                 CONNECTION_LOG(CONNECTION_INFO, "%s : %s", ETHERNET_MAC_INFO_FILE, buf);
583
584                 *mac_addr = (char *)malloc(CONNECTION_MAC_INFO_LENGTH + 1);
585                 if (*mac_addr == NULL) {
586                         CONNECTION_LOG(CONNECTION_ERROR, "malloc() failed");
587                         fclose(fp);
588                         return CONNECTION_ERROR_OUT_OF_MEMORY;
589                 }
590
591                 g_strlcpy(*mac_addr, buf,CONNECTION_MAC_INFO_LENGTH + 1);
592                 fclose(fp);
593
594                 break;
595         default:
596                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
597                 return CONNECTION_ERROR_INVALID_PARAMETER;
598         }
599
600         /* Checking Invalid MAC Address */
601         if((strcmp(*mac_addr, "00:00:00:00:00:00") == 0) ||
602                         (strcmp(*mac_addr, "ff:ff:ff:ff:ff:ff") == 0)) {
603                 CONNECTION_LOG(CONNECTION_ERROR, "MAC Address(%s) is invalid", *mac_addr);
604                 return CONNECTION_ERROR_INVALID_OPERATION;
605         }
606
607         CONNECTION_LOG(CONNECTION_INFO, "MAC Address %s", *mac_addr);
608
609         return CONNECTION_ERROR_NONE;
610 }
611
612 EXPORT_API int connection_get_cellular_state(connection_h connection, connection_cellular_state_e* state)
613 {
614         int rv = 0;
615         int status = 0;
616         int cellular_state = 0;
617 #if defined TIZEN_DUALSIM_ENABLE
618         int sim_id = 0;
619 #endif
620
621         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE);
622
623         if (state == NULL || !(__connection_check_handle_validity(connection))) {
624                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
625                 return CONNECTION_ERROR_INVALID_PARAMETER;
626         }
627
628         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &status);
629         if (rv != VCONF_OK) {
630                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get cellular state");
631                 return CONNECTION_ERROR_OPERATION_FAILED;
632         }
633
634         CONNECTION_LOG(CONNECTION_INFO, "Cellular: %d", status);
635         *state = __connection_convert_cellular_state(status);
636
637         if (*state == CONNECTION_CELLULAR_STATE_AVAILABLE) {
638 #if defined TIZEN_DUALSIM_ENABLE
639                 rv = vconf_get_int(VCONF_TELEPHONY_DEFAULT_DATA_SERVICE, &sim_id);
640                 if (rv != VCONF_OK) {
641                         CONNECTION_LOG(CONNECTION_ERROR,
642                                         "Failed to get default subscriber id", sim_id);
643                         return CONNECTION_ERROR_OPERATION_FAILED;
644                 }
645
646                 switch (sim_id) {
647                 case CONNECTION_CELLULAR_SUBSCRIBER_1:
648 #endif
649                         rv = vconf_get_int(VCONFKEY_DNET_STATE, &cellular_state);
650 #if defined TIZEN_DUALSIM_ENABLE
651                         break;
652
653                 case CONNECTION_CELLULAR_SUBSCRIBER_2:
654                         rv = vconf_get_int(VCONFKEY_DNET_STATE2, &cellular_state);
655                         break;
656
657                 default:
658                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid subscriber id:%d", sim_id);
659                         return CONNECTION_ERROR_OPERATION_FAILED;
660                 }
661 #endif
662                 if (rv != VCONF_OK) {
663                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to get cellular state");
664                         return CONNECTION_ERROR_OPERATION_FAILED;
665                 }
666         }
667
668         CONNECTION_LOG(CONNECTION_INFO, "Cellular state: %d", cellular_state);
669
670         if (cellular_state == VCONFKEY_DNET_NORMAL_CONNECTED ||
671                         cellular_state == VCONFKEY_DNET_SECURE_CONNECTED ||
672                         cellular_state == VCONFKEY_DNET_TRANSFER)
673                 *state = CONNECTION_CELLULAR_STATE_CONNECTED;
674
675         return CONNECTION_ERROR_NONE;
676 }
677
678 EXPORT_API int connection_get_wifi_state(connection_h connection, connection_wifi_state_e* state)
679 {
680         CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
681
682         if (state == NULL || !(__connection_check_handle_validity(connection))) {
683                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
684                 return CONNECTION_ERROR_INVALID_PARAMETER;
685         }
686
687         int rv = _connection_libnet_get_wifi_state(state);
688         if (rv != CONNECTION_ERROR_NONE) {
689                 CONNECTION_LOG(CONNECTION_ERROR, "Fail to get Wi-Fi state[%d]", rv);
690                 return rv;
691         }
692
693         CONNECTION_LOG(CONNECTION_INFO, "Wi-Fi state: %d", *state);
694
695         return CONNECTION_ERROR_NONE;
696 }
697
698 EXPORT_API int connection_get_ethernet_state(connection_h connection, connection_ethernet_state_e* state)
699 {
700         CHECK_FEATURE_SUPPORTED(ETHERNET_FEATURE);
701
702         if (state == NULL || !(__connection_check_handle_validity(connection))) {
703                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
704                 return CONNECTION_ERROR_INVALID_PARAMETER;
705         }
706
707         return _connection_libnet_get_ethernet_state(state);
708 }
709
710 EXPORT_API int connection_get_ethernet_cable_state(connection_h connection, connection_ethernet_cable_state_e *state)
711 {
712         CHECK_FEATURE_SUPPORTED(ETHERNET_FEATURE);
713
714         if (state == NULL || !(__connection_check_handle_validity(connection))) {
715                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
716                 return CONNECTION_ERROR_INVALID_PARAMETER;
717         }
718
719         return _connection_libnet_get_ethernet_cable_state(state);
720 }
721
722 EXPORT_API int connection_set_ethernet_cable_state_chaged_cb(connection_h connection,
723                           connection_ethernet_cable_state_chaged_cb callback, void *user_data)
724 {
725         CHECK_FEATURE_SUPPORTED(ETHERNET_FEATURE);
726
727         if (callback == NULL || !(__connection_check_handle_validity(connection))) {
728                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
729                 return CONNECTION_ERROR_INVALID_PARAMETER;
730         }
731
732         return __connection_set_ethernet_cable_state_changed_cb(connection,
733                                                         callback, user_data);
734 }
735
736 EXPORT_API int connection_unset_ethernet_cable_state_chaged_cb(connection_h connection)
737 {
738         CHECK_FEATURE_SUPPORTED(ETHERNET_FEATURE);
739
740         if ( !(__connection_check_handle_validity(connection)) ) {
741                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
742                 return CONNECTION_ERROR_INVALID_PARAMETER;
743         }
744
745         return __connection_set_ethernet_cable_state_changed_cb(connection,
746                                                         NULL, NULL);
747 }
748
749 EXPORT_API int connection_get_bt_state(connection_h connection, connection_bt_state_e* state)
750 {
751         CHECK_FEATURE_SUPPORTED(TETHERING_BLUETOOTH_FEATURE);
752
753         if (state == NULL || !(__connection_check_handle_validity(connection))) {
754                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
755                 return CONNECTION_ERROR_INVALID_PARAMETER;
756         }
757
758         return _connection_libnet_get_bluetooth_state(state);
759 }
760
761 EXPORT_API int connection_set_type_changed_cb(connection_h connection,
762                                         connection_type_changed_cb callback, void* user_data)
763 {
764         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
765
766         if (callback == NULL || !(__connection_check_handle_validity(connection))) {
767                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
768                 return CONNECTION_ERROR_INVALID_PARAMETER;
769         }
770
771         return __connection_set_type_changed_callback(connection, callback, user_data);
772 }
773
774 EXPORT_API int connection_unset_type_changed_cb(connection_h connection)
775 {
776         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
777
778         if (!(__connection_check_handle_validity(connection))) {
779                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
780                 return CONNECTION_ERROR_INVALID_PARAMETER;
781         }
782
783         return __connection_set_type_changed_callback(connection, NULL, NULL);
784 }
785
786 EXPORT_API int connection_set_ip_address_changed_cb(connection_h connection,
787                                 connection_address_changed_cb callback, void* user_data)
788 {
789         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
790
791         if (callback == NULL || !(__connection_check_handle_validity(connection))) {
792                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
793                 return CONNECTION_ERROR_INVALID_PARAMETER;
794         }
795
796         return __connection_set_ip_changed_callback(connection, callback, user_data);
797 }
798
799 EXPORT_API int connection_unset_ip_address_changed_cb(connection_h connection)
800 {
801         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
802
803         if (!(__connection_check_handle_validity(connection))) {
804                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
805                 return CONNECTION_ERROR_INVALID_PARAMETER;
806         }
807
808         return __connection_set_ip_changed_callback(connection, NULL, NULL);
809 }
810
811 EXPORT_API int connection_set_proxy_address_changed_cb(connection_h connection,
812                                 connection_address_changed_cb callback, void* user_data)
813 {
814         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
815
816         if (callback == NULL || !(__connection_check_handle_validity(connection))) {
817                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
818                 return CONNECTION_ERROR_INVALID_PARAMETER;
819         }
820
821         return __connection_set_proxy_changed_callback(connection, callback, user_data);
822 }
823
824 EXPORT_API int connection_unset_proxy_address_changed_cb(connection_h connection)
825 {
826         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
827
828         if (!(__connection_check_handle_validity(connection))) {
829                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
830                 return CONNECTION_ERROR_INVALID_PARAMETER;
831         }
832
833         return __connection_set_proxy_changed_callback(connection, NULL, NULL);
834 }
835
836 EXPORT_API int connection_add_profile(connection_h connection, connection_profile_h profile)
837 {
838         int rv = 0;
839         net_profile_info_t *profile_info = profile;
840
841         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE);
842
843         if (!(__connection_check_handle_validity(connection)) ||
844             !(_connection_libnet_check_profile_validity(profile))) {
845                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
846                 return CONNECTION_ERROR_INVALID_PARAMETER;
847         }
848
849         if (profile_info->profile_type != NET_DEVICE_CELLULAR) {
850                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
851                 return CONNECTION_ERROR_INVALID_PARAMETER;
852         }
853
854         if (profile_info->ProfileInfo.Pdp.PSModemPath[0] != '/' ||
855                         strlen(profile_info->ProfileInfo.Pdp.PSModemPath) < 2) {
856                 CONNECTION_LOG(CONNECTION_ERROR, "Modem object path is NULL");
857                 return CONNECTION_ERROR_INVALID_PARAMETER;
858         }
859
860         rv = net_add_profile(profile_info->ProfileInfo.Pdp.ServiceType,
861                                                         (net_profile_info_t*)profile);
862         if (rv == NET_ERR_ACCESS_DENIED) {
863                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
864                 return CONNECTION_ERROR_PERMISSION_DENIED;
865         } else if (rv != NET_ERR_NONE) {
866                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to add profile[%d]", rv);
867                 return CONNECTION_ERROR_OPERATION_FAILED;
868         }
869
870         return CONNECTION_ERROR_NONE;
871 }
872
873 EXPORT_API int connection_remove_profile(connection_h connection, connection_profile_h profile)
874 {
875         int rv = 0;
876         net_profile_info_t *profile_info = profile;
877
878         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE);
879
880         if (!(__connection_check_handle_validity(connection)) ||
881                         !(_connection_libnet_check_profile_validity(profile))) {
882                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
883                 return CONNECTION_ERROR_INVALID_PARAMETER;
884         }
885
886         if (profile_info->profile_type != NET_DEVICE_CELLULAR &&
887             profile_info->profile_type != NET_DEVICE_WIFI) {
888                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
889                 return CONNECTION_ERROR_INVALID_PARAMETER;
890         }
891
892         rv = net_delete_profile(profile_info->ProfileName);
893         if (rv == NET_ERR_ACCESS_DENIED) {
894                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
895                 return CONNECTION_ERROR_PERMISSION_DENIED;
896         } else if (rv != NET_ERR_NONE) {
897                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to delete profile[%d]", rv);
898                 return CONNECTION_ERROR_OPERATION_FAILED;
899         }
900
901         return CONNECTION_ERROR_NONE;
902 }
903
904 EXPORT_API int connection_update_profile(connection_h connection, connection_profile_h profile)
905 {
906         int rv = 0;
907         net_profile_info_t *profile_info = profile;
908
909         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, ETHERNET_FEATURE);
910
911         if (!(__connection_check_handle_validity(connection)) ||
912             !(_connection_libnet_check_profile_validity(profile))) {
913                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
914                 return CONNECTION_ERROR_INVALID_PARAMETER;
915         }
916
917         rv = net_modify_profile(profile_info->ProfileName, (net_profile_info_t*)profile);
918         if (rv == NET_ERR_ACCESS_DENIED) {
919                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
920                 return CONNECTION_ERROR_PERMISSION_DENIED;
921         } else if (rv != NET_ERR_NONE) {
922                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to modify profile[%d]", rv);
923                 return CONNECTION_ERROR_OPERATION_FAILED;
924         }
925
926         return CONNECTION_ERROR_NONE;
927 }
928
929 EXPORT_API int connection_get_profile_iterator(connection_h connection,
930                 connection_iterator_type_e type, connection_profile_iterator_h* profile_iterator)
931 {
932         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
933
934         if (!(__connection_check_handle_validity(connection)) ||
935             (type != CONNECTION_ITERATOR_TYPE_REGISTERED &&
936              type != CONNECTION_ITERATOR_TYPE_CONNECTED &&
937              type != CONNECTION_ITERATOR_TYPE_DEFAULT)) {
938                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
939                 return CONNECTION_ERROR_INVALID_PARAMETER;
940         }
941
942         return _connection_libnet_get_profile_iterator(type, profile_iterator);
943 }
944
945 EXPORT_API int connection_profile_iterator_next(connection_profile_iterator_h profile_iterator,
946                                                         connection_profile_h* profile)
947 {
948         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
949
950         return _connection_libnet_get_iterator_next(profile_iterator, profile);
951 }
952
953 EXPORT_API bool connection_profile_iterator_has_next(connection_profile_iterator_h profile_iterator)
954 {
955         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
956
957         return _connection_libnet_iterator_has_next(profile_iterator);
958 }
959
960 EXPORT_API int connection_destroy_profile_iterator(connection_profile_iterator_h profile_iterator)
961 {
962         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
963
964         return _connection_libnet_destroy_iterator(profile_iterator);
965 }
966
967 EXPORT_API int connection_get_current_profile(connection_h connection, connection_profile_h* profile)
968 {
969         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
970
971         if (!(__connection_check_handle_validity(connection)) || profile == NULL) {
972                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
973                 return CONNECTION_ERROR_INVALID_PARAMETER;
974         }
975
976         return _connection_libnet_get_current_profile(profile);
977 }
978
979 EXPORT_API int connection_get_default_cellular_service_profile(
980                 connection_h connection, connection_cellular_service_type_e type,
981                 connection_profile_h *profile)
982 {
983         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE);
984
985         if (!(__connection_check_handle_validity(connection)) || profile == NULL) {
986                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
987                 return CONNECTION_ERROR_INVALID_PARAMETER;
988         }
989
990         return _connection_libnet_get_cellular_service_profile(type, profile);
991 }
992
993 EXPORT_API int connection_set_default_cellular_service_profile(connection_h connection,
994                 connection_cellular_service_type_e type, connection_profile_h profile)
995 {
996         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE);
997
998         if (!(__connection_check_handle_validity(connection)) || profile == NULL) {
999                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1000                 return CONNECTION_ERROR_INVALID_PARAMETER;
1001         }
1002
1003         return _connection_libnet_set_cellular_service_profile_sync(type, profile);
1004 }
1005
1006 EXPORT_API int connection_set_default_cellular_service_profile_async(connection_h connection,
1007                 connection_cellular_service_type_e type, connection_profile_h profile,
1008                 connection_set_default_cb callback, void* user_data)
1009 {
1010         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE);
1011
1012         if (!(__connection_check_handle_validity(connection)) ||
1013             profile == NULL || callback == NULL) {
1014                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1015                 return CONNECTION_ERROR_INVALID_PARAMETER;
1016         }
1017
1018         return _connection_libnet_set_cellular_service_profile_async(type, profile, callback, user_data);
1019 }
1020
1021 EXPORT_API int connection_open_profile(connection_h connection, connection_profile_h profile,
1022                                         connection_opened_cb callback, void* user_data)
1023 {
1024         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE);
1025
1026         if (!(__connection_check_handle_validity(connection)) ||
1027             profile == NULL || callback == NULL) {
1028                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1029                 return CONNECTION_ERROR_INVALID_PARAMETER;
1030         }
1031
1032         return _connection_libnet_open_profile(profile, callback, user_data);
1033 }
1034
1035 EXPORT_API int connection_close_profile(connection_h connection, connection_profile_h profile,
1036                                         connection_closed_cb callback, void* user_data)
1037 {
1038         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE);
1039
1040         if (!(__connection_check_handle_validity(connection)) ||
1041             profile == NULL || callback == NULL) {
1042                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1043                 return CONNECTION_ERROR_INVALID_PARAMETER;
1044         }
1045
1046         return _connection_libnet_close_profile(profile, callback, user_data);
1047 }
1048
1049 EXPORT_API int connection_reset_profile(connection_h connection,
1050                                 connection_reset_option_e type, int id, connection_reset_cb callback, void *user_data)
1051 {
1052         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE);
1053
1054         if (!(__connection_check_handle_validity(connection))) {
1055                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed");
1056                 return CONNECTION_ERROR_INVALID_PARAMETER;
1057         }
1058
1059         if(id < 0 || id > 1) {
1060                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed");
1061                 return CONNECTION_ERROR_INVALID_PARAMETER;
1062         }
1063
1064         return _connection_libnet_reset_profile(type, id, callback, user_data);
1065 }
1066
1067 EXPORT_API int connection_add_route(connection_h connection, const char* interface_name, const char* host_address)
1068 {
1069         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
1070
1071         if (!(__connection_check_handle_validity(connection)) ||
1072             interface_name == NULL || host_address == NULL) {
1073                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1074                 return CONNECTION_ERROR_INVALID_PARAMETER;
1075         }
1076
1077         return _connection_libnet_add_route(interface_name, host_address);
1078 }
1079
1080 EXPORT_API int connection_remove_route(connection_h connection, const char* interface_name, const char* host_address)
1081 {
1082         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
1083
1084         if (!(__connection_check_handle_validity(connection)) ||
1085             interface_name == NULL || host_address == NULL) {
1086                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1087                 return CONNECTION_ERROR_INVALID_PARAMETER;
1088         }
1089
1090         return _connection_libnet_remove_route(interface_name, host_address);
1091 }
1092
1093 EXPORT_API int connection_add_route_ipv6(connection_h connection, const char *interface_name, const char *host_address, const char * gateway)
1094 {
1095         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, ETHERNET_FEATURE);
1096
1097         if (!(__connection_check_handle_validity(connection)) ||
1098             interface_name == NULL || host_address == NULL) {
1099                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1100                 return CONNECTION_ERROR_INVALID_PARAMETER;
1101         }
1102
1103         return _connection_libnet_add_route_ipv6(interface_name, host_address, gateway);
1104 }
1105
1106 EXPORT_API int connection_remove_route_ipv6(connection_h connection, const char *interface_name, const char *host_address, const char * gateway)
1107 {
1108         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, ETHERNET_FEATURE);
1109
1110         if (!(__connection_check_handle_validity(connection)) ||
1111             interface_name == NULL || host_address == NULL) {
1112                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1113                 return CONNECTION_ERROR_INVALID_PARAMETER;
1114         }
1115
1116         return _connection_libnet_remove_route_ipv6(interface_name, host_address, gateway);
1117 }
1118
1119 static int __get_cellular_statistic(connection_statistics_type_e statistics_type, long long *llsize)
1120 {
1121         int rv = VCONF_OK, rv1 = VCONF_OK;
1122         int last_size = 0, size = 0;
1123 #if defined TIZEN_DUALSIM_ENABLE
1124         int sim_id = 0;
1125 #endif
1126
1127         if (llsize == NULL) {
1128                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1129                 return CONNECTION_ERROR_INVALID_PARAMETER;
1130         }
1131
1132         switch (statistics_type) {
1133         case CONNECTION_STATISTICS_TYPE_LAST_SENT_DATA:
1134         case CONNECTION_STATISTICS_TYPE_LAST_RECEIVED_DATA:
1135         case CONNECTION_STATISTICS_TYPE_TOTAL_SENT_DATA:
1136         case CONNECTION_STATISTICS_TYPE_TOTAL_RECEIVED_DATA:
1137                 break;
1138         default:
1139                 return CONNECTION_ERROR_INVALID_PARAMETER;
1140         }
1141
1142 #if defined TIZEN_DUALSIM_ENABLE
1143         rv = vconf_get_int(VCONF_TELEPHONY_DEFAULT_DATA_SERVICE, &sim_id);
1144         if (rv != VCONF_OK) {
1145                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get default subscriber id");
1146                 *llsize = 0;
1147                 return CONNECTION_ERROR_OPERATION_FAILED;
1148         }
1149
1150         switch (sim_id) {
1151         case 0:
1152 #endif
1153                 switch (statistics_type) {
1154                 case CONNECTION_STATISTICS_TYPE_LAST_SENT_DATA:
1155                         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_SNT, &last_size);
1156                         break;
1157                 case CONNECTION_STATISTICS_TYPE_LAST_RECEIVED_DATA:
1158                         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_RCV, &last_size);
1159                         break;
1160                 case CONNECTION_STATISTICS_TYPE_TOTAL_SENT_DATA:
1161                         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_SNT, &last_size);
1162                         rv1 = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_SNT, &size);
1163                         break;
1164                 case CONNECTION_STATISTICS_TYPE_TOTAL_RECEIVED_DATA:
1165                         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_RCV, &last_size);
1166                         rv1 = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_RCV, &size);
1167                         break;
1168                 }
1169 #if defined TIZEN_DUALSIM_ENABLE
1170                 break;
1171         case 1:
1172                 switch (statistics_type) {
1173                 case CONNECTION_STATISTICS_TYPE_LAST_SENT_DATA:
1174                         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_SNT2, &last_size);
1175                         break;
1176                 case CONNECTION_STATISTICS_TYPE_LAST_RECEIVED_DATA:
1177                         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_RCV2, &last_size);
1178                         break;
1179                 case CONNECTION_STATISTICS_TYPE_TOTAL_SENT_DATA:
1180                         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_SNT2, &last_size);
1181                         rv1 = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_SNT2, &size);
1182                         break;
1183                 case CONNECTION_STATISTICS_TYPE_TOTAL_RECEIVED_DATA:
1184                         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_RCV2, &last_size);
1185                         rv1 = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_RCV2, &size);
1186                         break;
1187                 }
1188                 break;
1189         default:
1190                 *llsize = 0;
1191                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid subscriber id:%d", sim_id);
1192                 return CONNECTION_ERROR_OPERATION_FAILED;
1193         }
1194 #endif
1195
1196         if (rv != VCONF_OK || rv1 != VCONF_OK) {
1197                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get cellular statistics");
1198                 return CONNECTION_ERROR_OPERATION_FAILED;
1199         }
1200
1201         *llsize = (long long)(last_size * 1000 + size * 1000);
1202         CONNECTION_LOG(CONNECTION_INFO,"%lld bytes", *llsize);
1203
1204         return CONNECTION_ERROR_NONE;
1205 }
1206
1207 static int __get_statistic(connection_type_e connection_type,
1208                 connection_statistics_type_e statistics_type, long long *llsize)
1209 {
1210         int rv, stat_type;
1211         unsigned long long ull_size;
1212
1213         if (llsize == NULL) {
1214                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1215                 return CONNECTION_ERROR_INVALID_PARAMETER;
1216         }
1217
1218         rv  = _connection_libnet_check_get_privilege();
1219         if (rv == CONNECTION_ERROR_PERMISSION_DENIED)
1220                 return rv;
1221         else if (rv != CONNECTION_ERROR_NONE) {
1222                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get statistics");
1223                 return CONNECTION_ERROR_OPERATION_FAILED;
1224         }
1225
1226         if (connection_type == CONNECTION_TYPE_CELLULAR)
1227                 return __get_cellular_statistic(statistics_type, llsize);
1228         else if (connection_type == CONNECTION_TYPE_WIFI) {
1229                 switch (statistics_type) {
1230                 case CONNECTION_STATISTICS_TYPE_LAST_SENT_DATA:
1231                         stat_type = NET_STATISTICS_TYPE_LAST_SENT_DATA;
1232                         break;
1233                 case CONNECTION_STATISTICS_TYPE_LAST_RECEIVED_DATA:
1234                         stat_type = NET_STATISTICS_TYPE_LAST_RECEIVED_DATA;
1235                         break;
1236                 case CONNECTION_STATISTICS_TYPE_TOTAL_SENT_DATA:
1237                         stat_type = NET_STATISTICS_TYPE_TOTAL_SENT_DATA;
1238                         break;
1239                 case CONNECTION_STATISTICS_TYPE_TOTAL_RECEIVED_DATA:
1240                         stat_type = NET_STATISTICS_TYPE_TOTAL_RECEIVED_DATA;
1241                         break;
1242                 default:
1243                         return CONNECTION_ERROR_INVALID_PARAMETER;
1244                 }
1245
1246                 rv  = _connection_libnet_get_statistics(stat_type, &ull_size);
1247                 if (rv == CONNECTION_ERROR_PERMISSION_DENIED)
1248                         return rv;
1249                 else if (rv != CONNECTION_ERROR_NONE) {
1250                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to get Wi-Fi statistics");
1251                         *llsize = 0;
1252                         return CONNECTION_ERROR_OPERATION_FAILED;
1253                 }
1254
1255                 CONNECTION_LOG(CONNECTION_INFO,"%lld bytes", ull_size);
1256                 *llsize = (long long)ull_size;
1257         } else
1258                 return CONNECTION_ERROR_INVALID_PARAMETER;
1259
1260         return CONNECTION_ERROR_NONE;
1261 }
1262
1263 static int __reset_statistic(connection_type_e connection_type,
1264                 connection_statistics_type_e statistics_type)
1265 {
1266         int conn_type;
1267         int stat_type;
1268         int rv;
1269
1270         if (connection_type == CONNECTION_TYPE_CELLULAR)
1271                 conn_type = NET_DEVICE_CELLULAR;
1272         else if (connection_type == CONNECTION_TYPE_WIFI)
1273                 conn_type = NET_DEVICE_WIFI;
1274         else
1275                 return CONNECTION_ERROR_INVALID_PARAMETER;
1276
1277         switch (statistics_type) {
1278         case CONNECTION_STATISTICS_TYPE_LAST_SENT_DATA:
1279                 stat_type = NET_STATISTICS_TYPE_LAST_SENT_DATA;
1280                 break;
1281         case CONNECTION_STATISTICS_TYPE_LAST_RECEIVED_DATA:
1282                 stat_type = NET_STATISTICS_TYPE_LAST_RECEIVED_DATA;
1283                 break;
1284         case CONNECTION_STATISTICS_TYPE_TOTAL_SENT_DATA:
1285                 stat_type = NET_STATISTICS_TYPE_TOTAL_SENT_DATA;
1286                 break;
1287         case CONNECTION_STATISTICS_TYPE_TOTAL_RECEIVED_DATA:
1288                 stat_type = NET_STATISTICS_TYPE_TOTAL_RECEIVED_DATA;
1289                 break;
1290         default:
1291                 return CONNECTION_ERROR_INVALID_PARAMETER;
1292         }
1293
1294         rv = _connection_libnet_set_statistics(conn_type, stat_type);
1295         if (rv != CONNECTION_ERROR_NONE)
1296                 return rv;
1297
1298         CONNECTION_LOG(CONNECTION_INFO,"connection_reset_statistics success");
1299
1300         return CONNECTION_ERROR_NONE;
1301 }
1302
1303 EXPORT_API int connection_get_statistics(connection_h connection,
1304                                 connection_type_e connection_type,
1305                                 connection_statistics_type_e statistics_type, long long* size)
1306 {
1307         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE);
1308
1309         if(connection_type == CONNECTION_TYPE_CELLULAR )
1310                 CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE);
1311         else if(connection_type == CONNECTION_TYPE_WIFI)
1312                 CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
1313
1314         if (!(__connection_check_handle_validity(connection)) || size == NULL) {
1315                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1316                 return CONNECTION_ERROR_INVALID_PARAMETER;
1317         }
1318
1319         return __get_statistic(connection_type, statistics_type, size);
1320 }
1321
1322 EXPORT_API int connection_reset_statistics(connection_h connection,
1323                                 connection_type_e connection_type,
1324                                 connection_statistics_type_e statistics_type)
1325 {
1326         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE);
1327
1328         if(connection_type == CONNECTION_TYPE_CELLULAR )
1329                 CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE);
1330         else if(connection_type == CONNECTION_TYPE_WIFI)
1331                 CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
1332
1333         if (!__connection_check_handle_validity(connection)) {
1334                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1335                 return CONNECTION_ERROR_INVALID_PARAMETER;
1336         }
1337
1338         return __reset_statistic(connection_type, statistics_type);
1339 }
1340