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