3d138997a4218187f97b92568f7cf3ae6cbdf1f7
[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         }
403         else if (rv != NET_ERR_NONE) {
404                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to create connection[%d]", rv);
405                 return CONNECTION_ERROR_OPERATION_FAILED;
406         }
407
408         *connection = g_try_malloc0(sizeof(connection_handle_s));
409         if (*connection != NULL)
410                 CONNECTION_LOG(CONNECTION_INFO, "New handle created[%p]", *connection);
411         else
412                 return CONNECTION_ERROR_OUT_OF_MEMORY;
413
414         conn_handle_list = g_slist_prepend(conn_handle_list, *connection);
415
416         return CONNECTION_ERROR_NONE;
417 }
418
419 EXPORT_API int connection_destroy(connection_h connection)
420 {
421         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
422
423         if (!(__connection_check_handle_validity(connection))) {
424                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
425                 return CONNECTION_ERROR_INVALID_PARAMETER;
426         }
427
428         CONNECTION_LOG(CONNECTION_INFO, "Destroy handle: %p", connection);
429
430         __connection_set_type_changed_callback(connection, NULL, NULL);
431         __connection_set_ip_changed_callback(connection, NULL, NULL);
432         __connection_set_proxy_changed_callback(connection, NULL, NULL);
433         __connection_set_ethernet_cable_state_changed_cb(connection, NULL, NULL);
434
435         conn_handle_list = g_slist_remove(conn_handle_list, connection);
436
437         g_free(connection);
438         connection = NULL;
439
440         if (__connection_get_handle_count() == 0) {
441                 _connection_libnet_deinit();
442                 _connection_callback_cleanup();
443         }
444
445         return CONNECTION_ERROR_NONE;
446 }
447
448 EXPORT_API int connection_get_type(connection_h connection, connection_type_e* type)
449 {
450         int rv = 0;
451         int status = 0;
452
453         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
454
455         if (type == NULL || !(__connection_check_handle_validity(connection))) {
456                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
457                 return CONNECTION_ERROR_INVALID_PARAMETER;
458         }
459
460         rv = vconf_get_int(VCONFKEY_NETWORK_STATUS, &status);
461         if (rv != VCONF_OK) {
462                 CONNECTION_LOG(CONNECTION_ERROR, "vconf_get_int Failed = %d", status);
463                 return CONNECTION_ERROR_OPERATION_FAILED;
464         }
465
466         CONNECTION_LOG(CONNECTION_INFO, "Connected Network = %d", status);
467
468         *type = __connection_convert_net_state(status);
469
470         return CONNECTION_ERROR_NONE;
471 }
472
473 EXPORT_API int connection_get_ip_address(connection_h connection,
474                                 connection_address_family_e address_family, char** ip_address)
475 {
476         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
477
478         if (ip_address == NULL || !(__connection_check_handle_validity(connection))) {
479                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
480                 return CONNECTION_ERROR_INVALID_PARAMETER;
481         }
482
483         switch (address_family) {
484         case CONNECTION_ADDRESS_FAMILY_IPV4:
485         case CONNECTION_ADDRESS_FAMILY_IPV6:
486                 *ip_address = vconf_get_str(VCONFKEY_NETWORK_IP);
487                 break;
488         default:
489                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
490                 return CONNECTION_ERROR_INVALID_PARAMETER;
491         }
492
493         if (*ip_address == NULL) {
494                 CONNECTION_LOG(CONNECTION_ERROR, "vconf_get_str Failed");
495                 return CONNECTION_ERROR_OPERATION_FAILED;
496         }
497
498         return CONNECTION_ERROR_NONE;
499 }
500
501 EXPORT_API int connection_get_proxy(connection_h connection,
502                                 connection_address_family_e address_family, char** proxy)
503 {
504         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
505
506         if (proxy == NULL || !(__connection_check_handle_validity(connection))) {
507                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
508                 return CONNECTION_ERROR_INVALID_PARAMETER;
509         }
510
511         switch (address_family) {
512         case CONNECTION_ADDRESS_FAMILY_IPV4:
513         case CONNECTION_ADDRESS_FAMILY_IPV6:
514                 *proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY);
515                 break;
516         default:
517                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
518                 return CONNECTION_ERROR_INVALID_PARAMETER;
519         }
520
521         if (*proxy == NULL) {
522                 CONNECTION_LOG(CONNECTION_ERROR, "vconf_get_str Failed");
523                 return CONNECTION_ERROR_OPERATION_FAILED;
524         }
525
526         return CONNECTION_ERROR_NONE;
527 }
528
529 EXPORT_API int connection_get_mac_address(connection_h connection, connection_type_e type, char** mac_addr)
530 {
531         FILE *fp;
532         char buf[CONNECTION_MAC_INFO_LENGTH + 1];
533
534         CHECK_FEATURE_SUPPORTED(WIFI_FEATURE, ETHERNET_FEATURE);
535
536         if(type == CONNECTION_TYPE_WIFI)
537                 CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
538         else if(type == CONNECTION_TYPE_ETHERNET)
539                 CHECK_FEATURE_SUPPORTED(ETHERNET_FEATURE);
540
541         if (mac_addr == NULL || !(__connection_check_handle_validity(connection))) {
542                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
543                 return CONNECTION_ERROR_INVALID_PARAMETER;
544         }
545
546         switch (type) {
547         case CONNECTION_TYPE_WIFI:
548                 fp = fopen(WIFI_MAC_INFO_FILE, "r");
549                 if (fp == NULL) {
550                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to open file %s", WIFI_MAC_INFO_FILE);
551                         return CONNECTION_ERROR_OUT_OF_MEMORY;
552                 }
553
554                 if (fgets(buf, sizeof(buf), fp) == NULL) {
555                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to get MAC info from %s", WIFI_MAC_INFO_FILE);
556                         fclose(fp);
557                         return CONNECTION_ERROR_OPERATION_FAILED;
558                 }
559
560                 CONNECTION_LOG(CONNECTION_INFO, "%s : %s", WIFI_MAC_INFO_FILE, buf);
561
562                 *mac_addr = (char *)malloc(CONNECTION_MAC_INFO_LENGTH + 1);
563                 if (*mac_addr == NULL) {
564                         CONNECTION_LOG(CONNECTION_ERROR, "malloc() failed");
565                         fclose(fp);
566                         return CONNECTION_ERROR_OUT_OF_MEMORY;
567                 }
568                 g_strlcpy(*mac_addr, buf, CONNECTION_MAC_INFO_LENGTH + 1);
569                 fclose(fp);
570                 break;
571         case CONNECTION_TYPE_ETHERNET:
572                 fp = fopen(ETHERNET_MAC_INFO_FILE, "r");
573                 if (fp == NULL) {
574                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to open file %s", ETHERNET_MAC_INFO_FILE);
575                         return CONNECTION_ERROR_OUT_OF_MEMORY;
576                 }
577
578                 if (fgets(buf, sizeof(buf), fp) == NULL) {
579                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to get MAC info from %s", ETHERNET_MAC_INFO_FILE);
580                         fclose(fp);
581                         return CONNECTION_ERROR_OPERATION_FAILED;
582                 }
583
584                 CONNECTION_LOG(CONNECTION_INFO, "%s : %s", ETHERNET_MAC_INFO_FILE, buf);
585
586                 *mac_addr = (char *)malloc(CONNECTION_MAC_INFO_LENGTH + 1);
587                 if (*mac_addr == NULL) {
588                         CONNECTION_LOG(CONNECTION_ERROR, "malloc() failed");
589                         fclose(fp);
590                         return CONNECTION_ERROR_OUT_OF_MEMORY;
591                 }
592
593                 g_strlcpy(*mac_addr, buf,CONNECTION_MAC_INFO_LENGTH + 1);
594                 fclose(fp);
595
596                 break;
597         default:
598                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
599                 return CONNECTION_ERROR_INVALID_PARAMETER;
600         }
601
602         /* Checking Invalid MAC Address */
603         if((strcmp(*mac_addr, "00:00:00:00:00:00") == 0) ||
604                         (strcmp(*mac_addr, "ff:ff:ff:ff:ff:ff") == 0)) {
605                 CONNECTION_LOG(CONNECTION_ERROR, "MAC Address(%s) is invalid", *mac_addr);
606                 return CONNECTION_ERROR_INVALID_OPERATION;
607         }
608
609         CONNECTION_LOG(CONNECTION_INFO, "MAC Address %s", *mac_addr);
610
611         return CONNECTION_ERROR_NONE;
612 }
613
614 EXPORT_API int connection_get_cellular_state(connection_h connection, connection_cellular_state_e* state)
615 {
616         int rv = 0;
617         int status = 0;
618         int cellular_state = 0;
619 #if defined TIZEN_DUALSIM_ENABLE
620         int sim_id = 0;
621 #endif
622
623         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE);
624
625         if (state == NULL || !(__connection_check_handle_validity(connection))) {
626                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
627                 return CONNECTION_ERROR_INVALID_PARAMETER;
628         }
629
630         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &status);
631         if (rv != VCONF_OK) {
632                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get cellular state");
633                 return CONNECTION_ERROR_OPERATION_FAILED;
634         }
635
636         CONNECTION_LOG(CONNECTION_INFO, "Cellular: %d", status);
637         *state = __connection_convert_cellular_state(status);
638
639         if (*state == CONNECTION_CELLULAR_STATE_AVAILABLE) {
640 #if defined TIZEN_DUALSIM_ENABLE
641                 rv = vconf_get_int(VCONF_TELEPHONY_DEFAULT_DATA_SERVICE, &sim_id);
642                 if (rv != VCONF_OK) {
643                         CONNECTION_LOG(CONNECTION_ERROR,
644                                         "Failed to get default subscriber id", sim_id);
645                         return CONNECTION_ERROR_OPERATION_FAILED;
646                 }
647
648                 switch (sim_id) {
649                 case CONNECTION_CELLULAR_SUBSCRIBER_1:
650 #endif
651                         rv = vconf_get_int(VCONFKEY_DNET_STATE, &cellular_state);
652 #if defined TIZEN_DUALSIM_ENABLE
653                         break;
654
655                 case CONNECTION_CELLULAR_SUBSCRIBER_2:
656                         rv = vconf_get_int(VCONFKEY_DNET_STATE2, &cellular_state);
657                         break;
658
659                 default:
660                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid subscriber id:%d", sim_id);
661                         return CONNECTION_ERROR_OPERATION_FAILED;
662                 }
663 #endif
664                 if (rv != VCONF_OK) {
665                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to get cellular state");
666                         return CONNECTION_ERROR_OPERATION_FAILED;
667                 }
668         }
669
670         CONNECTION_LOG(CONNECTION_INFO, "Cellular state: %d", cellular_state);
671
672         if (cellular_state == VCONFKEY_DNET_NORMAL_CONNECTED ||
673                         cellular_state == VCONFKEY_DNET_SECURE_CONNECTED ||
674                         cellular_state == VCONFKEY_DNET_TRANSFER)
675                 *state = CONNECTION_CELLULAR_STATE_CONNECTED;
676
677         return CONNECTION_ERROR_NONE;
678 }
679
680 EXPORT_API int connection_get_wifi_state(connection_h connection, connection_wifi_state_e* state)
681 {
682         CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
683
684         if (state == NULL || !(__connection_check_handle_validity(connection))) {
685                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
686                 return CONNECTION_ERROR_INVALID_PARAMETER;
687         }
688
689         int rv = _connection_libnet_get_wifi_state(state);
690         if (rv != CONNECTION_ERROR_NONE) {
691                 CONNECTION_LOG(CONNECTION_ERROR, "Fail to get Wi-Fi state[%d]", rv);
692                 return rv;
693         }
694
695         CONNECTION_LOG(CONNECTION_INFO, "Wi-Fi state: %d", *state);
696
697         return CONNECTION_ERROR_NONE;
698 }
699
700 EXPORT_API int connection_get_ethernet_state(connection_h connection, connection_ethernet_state_e* state)
701 {
702         CHECK_FEATURE_SUPPORTED(ETHERNET_FEATURE);
703
704         if (state == NULL || !(__connection_check_handle_validity(connection))) {
705                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
706                 return CONNECTION_ERROR_INVALID_PARAMETER;
707         }
708
709         return _connection_libnet_get_ethernet_state(state);
710 }
711
712 EXPORT_API int connection_get_ethernet_cable_state(connection_h connection, connection_ethernet_cable_state_e *state)
713 {
714         CHECK_FEATURE_SUPPORTED(ETHERNET_FEATURE);
715
716         if (state == NULL || !(__connection_check_handle_validity(connection))) {
717                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
718                 return CONNECTION_ERROR_INVALID_PARAMETER;
719         }
720
721         return _connection_libnet_get_ethernet_cable_state(state);
722 }
723
724 EXPORT_API int connection_set_ethernet_cable_state_chaged_cb(connection_h connection,
725                           connection_ethernet_cable_state_chaged_cb callback, void *user_data)
726 {
727         CHECK_FEATURE_SUPPORTED(ETHERNET_FEATURE);
728
729         if (callback == NULL || !(__connection_check_handle_validity(connection))) {
730                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
731                 return CONNECTION_ERROR_INVALID_PARAMETER;
732         }
733
734         return __connection_set_ethernet_cable_state_changed_cb(connection,
735                                                         callback, user_data);
736 }
737
738 EXPORT_API int connection_unset_ethernet_cable_state_chaged_cb(connection_h connection)
739 {
740         CHECK_FEATURE_SUPPORTED(ETHERNET_FEATURE);
741
742         if ( !(__connection_check_handle_validity(connection)) ) {
743                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
744                 return CONNECTION_ERROR_INVALID_PARAMETER;
745         }
746
747         return __connection_set_ethernet_cable_state_changed_cb(connection,
748                                                         NULL, NULL);
749 }
750
751 EXPORT_API int connection_get_bt_state(connection_h connection, connection_bt_state_e* state)
752 {
753         CHECK_FEATURE_SUPPORTED(TETHERING_BLUETOOTH_FEATURE);
754
755         if (state == NULL || !(__connection_check_handle_validity(connection))) {
756                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
757                 return CONNECTION_ERROR_INVALID_PARAMETER;
758         }
759
760         return _connection_libnet_get_bluetooth_state(state);
761 }
762
763 EXPORT_API int connection_set_type_changed_cb(connection_h connection,
764                                         connection_type_changed_cb callback, void* user_data)
765 {
766         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
767
768         if (callback == NULL || !(__connection_check_handle_validity(connection))) {
769                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
770                 return CONNECTION_ERROR_INVALID_PARAMETER;
771         }
772
773         return __connection_set_type_changed_callback(connection, callback, user_data);
774 }
775
776 EXPORT_API int connection_unset_type_changed_cb(connection_h connection)
777 {
778         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
779
780         if (!(__connection_check_handle_validity(connection))) {
781                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
782                 return CONNECTION_ERROR_INVALID_PARAMETER;
783         }
784
785         return __connection_set_type_changed_callback(connection, NULL, NULL);
786 }
787
788 EXPORT_API int connection_set_ip_address_changed_cb(connection_h connection,
789                                 connection_address_changed_cb callback, void* user_data)
790 {
791         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
792
793         if (callback == NULL || !(__connection_check_handle_validity(connection))) {
794                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
795                 return CONNECTION_ERROR_INVALID_PARAMETER;
796         }
797
798         return __connection_set_ip_changed_callback(connection, callback, user_data);
799 }
800
801 EXPORT_API int connection_unset_ip_address_changed_cb(connection_h connection)
802 {
803         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
804
805         if (!(__connection_check_handle_validity(connection))) {
806                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
807                 return CONNECTION_ERROR_INVALID_PARAMETER;
808         }
809
810         return __connection_set_ip_changed_callback(connection, NULL, NULL);
811 }
812
813 EXPORT_API int connection_set_proxy_address_changed_cb(connection_h connection,
814                                 connection_address_changed_cb callback, void* user_data)
815 {
816         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
817
818         if (callback == NULL || !(__connection_check_handle_validity(connection))) {
819                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
820                 return CONNECTION_ERROR_INVALID_PARAMETER;
821         }
822
823         return __connection_set_proxy_changed_callback(connection, callback, user_data);
824 }
825
826 EXPORT_API int connection_unset_proxy_address_changed_cb(connection_h connection)
827 {
828         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
829
830         if (!(__connection_check_handle_validity(connection))) {
831                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
832                 return CONNECTION_ERROR_INVALID_PARAMETER;
833         }
834
835         return __connection_set_proxy_changed_callback(connection, NULL, NULL);
836 }
837
838 EXPORT_API int connection_add_profile(connection_h connection, connection_profile_h profile)
839 {
840         int rv = 0;
841         net_profile_info_t *profile_info = profile;
842
843         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE);
844
845         if (!(__connection_check_handle_validity(connection)) ||
846             !(_connection_libnet_check_profile_validity(profile))) {
847                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
848                 return CONNECTION_ERROR_INVALID_PARAMETER;
849         }
850
851         if (profile_info->profile_type != NET_DEVICE_CELLULAR) {
852                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
853                 return CONNECTION_ERROR_INVALID_PARAMETER;
854         }
855
856         if (profile_info->ProfileInfo.Pdp.PSModemPath[0] != '/' ||
857                         strlen(profile_info->ProfileInfo.Pdp.PSModemPath) < 2) {
858                 CONNECTION_LOG(CONNECTION_ERROR, "Modem object path is NULL");
859                 return CONNECTION_ERROR_INVALID_PARAMETER;
860         }
861
862         rv = net_add_profile(profile_info->ProfileInfo.Pdp.ServiceType,
863                                                         (net_profile_info_t*)profile);
864         if (rv == NET_ERR_ACCESS_DENIED) {
865                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
866                 return CONNECTION_ERROR_PERMISSION_DENIED;
867         } else if (rv != NET_ERR_NONE) {
868                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to add profile[%d]", rv);
869                 return CONNECTION_ERROR_OPERATION_FAILED;
870         }
871
872         return CONNECTION_ERROR_NONE;
873 }
874
875 EXPORT_API int connection_remove_profile(connection_h connection, connection_profile_h profile)
876 {
877         int rv = 0;
878         net_profile_info_t *profile_info = profile;
879
880         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE);
881
882         if (!(__connection_check_handle_validity(connection)) ||
883                         !(_connection_libnet_check_profile_validity(profile))) {
884                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
885                 return CONNECTION_ERROR_INVALID_PARAMETER;
886         }
887
888         if (profile_info->profile_type != NET_DEVICE_CELLULAR &&
889             profile_info->profile_type != NET_DEVICE_WIFI) {
890                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
891                 return CONNECTION_ERROR_INVALID_PARAMETER;
892         }
893
894         rv = net_delete_profile(profile_info->ProfileName);
895         if (rv == NET_ERR_ACCESS_DENIED) {
896                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
897                 return CONNECTION_ERROR_PERMISSION_DENIED;
898         } else if (rv != NET_ERR_NONE) {
899                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to delete profile[%d]", rv);
900                 return CONNECTION_ERROR_OPERATION_FAILED;
901         }
902
903         return CONNECTION_ERROR_NONE;
904 }
905
906 EXPORT_API int connection_update_profile(connection_h connection, connection_profile_h profile)
907 {
908         int rv = 0;
909         net_profile_info_t *profile_info = profile;
910
911         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, ETHERNET_FEATURE);
912
913         if (!(__connection_check_handle_validity(connection)) ||
914             !(_connection_libnet_check_profile_validity(profile))) {
915                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
916                 return CONNECTION_ERROR_INVALID_PARAMETER;
917         }
918
919         rv = net_modify_profile(profile_info->ProfileName, (net_profile_info_t*)profile);
920         if (rv == NET_ERR_ACCESS_DENIED) {
921                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
922                 return CONNECTION_ERROR_PERMISSION_DENIED;
923         } else if (rv != NET_ERR_NONE) {
924                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to modify profile[%d]", rv);
925                 return CONNECTION_ERROR_OPERATION_FAILED;
926         }
927
928         return CONNECTION_ERROR_NONE;
929 }
930
931 EXPORT_API int connection_get_profile_iterator(connection_h connection,
932                 connection_iterator_type_e type, connection_profile_iterator_h* profile_iterator)
933 {
934         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
935
936         if (!(__connection_check_handle_validity(connection)) ||
937             (type != CONNECTION_ITERATOR_TYPE_REGISTERED &&
938              type != CONNECTION_ITERATOR_TYPE_CONNECTED &&
939              type != CONNECTION_ITERATOR_TYPE_DEFAULT)) {
940                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
941                 return CONNECTION_ERROR_INVALID_PARAMETER;
942         }
943
944         return _connection_libnet_get_profile_iterator(type, profile_iterator);
945 }
946
947 EXPORT_API int connection_profile_iterator_next(connection_profile_iterator_h profile_iterator,
948                                                         connection_profile_h* profile)
949 {
950         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
951
952         return _connection_libnet_get_iterator_next(profile_iterator, profile);
953 }
954
955 EXPORT_API bool connection_profile_iterator_has_next(connection_profile_iterator_h profile_iterator)
956 {
957         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
958
959         return _connection_libnet_iterator_has_next(profile_iterator);
960 }
961
962 EXPORT_API int connection_destroy_profile_iterator(connection_profile_iterator_h profile_iterator)
963 {
964         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
965
966         return _connection_libnet_destroy_iterator(profile_iterator);
967 }
968
969 EXPORT_API int connection_get_current_profile(connection_h connection, connection_profile_h* profile)
970 {
971         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
972
973         if (!(__connection_check_handle_validity(connection)) || profile == NULL) {
974                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
975                 return CONNECTION_ERROR_INVALID_PARAMETER;
976         }
977
978         return _connection_libnet_get_current_profile(profile);
979 }
980
981 EXPORT_API int connection_get_default_cellular_service_profile(
982                 connection_h connection, connection_cellular_service_type_e type,
983                 connection_profile_h *profile)
984 {
985         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE);
986
987         if (!(__connection_check_handle_validity(connection)) || profile == NULL) {
988                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
989                 return CONNECTION_ERROR_INVALID_PARAMETER;
990         }
991
992         return _connection_libnet_get_cellular_service_profile(type, profile);
993 }
994
995 EXPORT_API int connection_set_default_cellular_service_profile(connection_h connection,
996                 connection_cellular_service_type_e type, connection_profile_h profile)
997 {
998         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE);
999
1000         if (!(__connection_check_handle_validity(connection)) || profile == NULL) {
1001                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1002                 return CONNECTION_ERROR_INVALID_PARAMETER;
1003         }
1004
1005         return _connection_libnet_set_cellular_service_profile_sync(type, profile);
1006 }
1007
1008 EXPORT_API int connection_set_default_cellular_service_profile_async(connection_h connection,
1009                 connection_cellular_service_type_e type, connection_profile_h profile,
1010                 connection_set_default_cb callback, void* user_data)
1011 {
1012         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE);
1013
1014         if (!(__connection_check_handle_validity(connection)) ||
1015             profile == NULL || callback == NULL) {
1016                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1017                 return CONNECTION_ERROR_INVALID_PARAMETER;
1018         }
1019
1020         return _connection_libnet_set_cellular_service_profile_async(type, profile, callback, user_data);
1021 }
1022
1023 EXPORT_API int connection_open_profile(connection_h connection, connection_profile_h profile,
1024                                         connection_opened_cb callback, void* user_data)
1025 {
1026         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE);
1027
1028         if (!(__connection_check_handle_validity(connection)) ||
1029             profile == NULL || callback == NULL) {
1030                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1031                 return CONNECTION_ERROR_INVALID_PARAMETER;
1032         }
1033
1034         return _connection_libnet_open_profile(profile, callback, user_data);
1035 }
1036
1037 EXPORT_API int connection_close_profile(connection_h connection, connection_profile_h profile,
1038                                         connection_closed_cb callback, void* user_data)
1039 {
1040         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE);
1041
1042         if (!(__connection_check_handle_validity(connection)) ||
1043             profile == NULL || callback == NULL) {
1044                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1045                 return CONNECTION_ERROR_INVALID_PARAMETER;
1046         }
1047
1048         return _connection_libnet_close_profile(profile, callback, user_data);
1049 }
1050
1051 EXPORT_API int connection_reset_profile(connection_h connection,
1052                                 connection_reset_option_e type, int id, connection_reset_cb callback, void *user_data)
1053 {
1054         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE);
1055
1056         if (!(__connection_check_handle_validity(connection))) {
1057                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed");
1058                 return CONNECTION_ERROR_INVALID_PARAMETER;
1059         }
1060
1061         if(id < 0 || id > 1) {
1062                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed");
1063                 return CONNECTION_ERROR_INVALID_PARAMETER;
1064         }
1065
1066         return _connection_libnet_reset_profile(type, id, callback, user_data);
1067 }
1068
1069 EXPORT_API int connection_add_route(connection_h connection, const char* interface_name, const char* host_address)
1070 {
1071         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
1072
1073         if (!(__connection_check_handle_validity(connection)) ||
1074             interface_name == NULL || host_address == NULL) {
1075                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1076                 return CONNECTION_ERROR_INVALID_PARAMETER;
1077         }
1078
1079         return _connection_libnet_add_route(interface_name, host_address);
1080 }
1081
1082 EXPORT_API int connection_remove_route(connection_h connection, const char* interface_name, const char* host_address)
1083 {
1084         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, TETHERING_BLUETOOTH_FEATURE, ETHERNET_FEATURE);
1085
1086         if (!(__connection_check_handle_validity(connection)) ||
1087             interface_name == NULL || host_address == NULL) {
1088                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1089                 return CONNECTION_ERROR_INVALID_PARAMETER;
1090         }
1091
1092         return _connection_libnet_remove_route(interface_name, host_address);
1093 }
1094
1095 EXPORT_API int connection_add_route_ipv6(connection_h connection, const char *interface_name, const char *host_address, const char * gateway)
1096 {
1097         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, ETHERNET_FEATURE);
1098
1099         if (!(__connection_check_handle_validity(connection)) ||
1100             interface_name == NULL || host_address == NULL) {
1101                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1102                 return CONNECTION_ERROR_INVALID_PARAMETER;
1103         }
1104
1105         return _connection_libnet_add_route_ipv6(interface_name, host_address, gateway);
1106 }
1107
1108 EXPORT_API int connection_remove_route_ipv6(connection_h connection, const char *interface_name, const char *host_address, const char * gateway)
1109 {
1110         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE, ETHERNET_FEATURE);
1111
1112         if (!(__connection_check_handle_validity(connection)) ||
1113             interface_name == NULL || host_address == NULL) {
1114                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1115                 return CONNECTION_ERROR_INVALID_PARAMETER;
1116         }
1117
1118         return _connection_libnet_remove_route_ipv6(interface_name, host_address, gateway);
1119 }
1120
1121 static int __get_cellular_statistic(connection_statistics_type_e statistics_type, long long *llsize)
1122 {
1123         int rv = VCONF_OK, rv1 = VCONF_OK;
1124         int last_size = 0, size = 0;
1125 #if defined TIZEN_DUALSIM_ENABLE
1126         int sim_id = 0;
1127 #endif
1128
1129         if (llsize == NULL) {
1130                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1131                 return CONNECTION_ERROR_INVALID_PARAMETER;
1132         }
1133
1134         switch (statistics_type) {
1135         case CONNECTION_STATISTICS_TYPE_LAST_SENT_DATA:
1136         case CONNECTION_STATISTICS_TYPE_LAST_RECEIVED_DATA:
1137         case CONNECTION_STATISTICS_TYPE_TOTAL_SENT_DATA:
1138         case CONNECTION_STATISTICS_TYPE_TOTAL_RECEIVED_DATA:
1139                 break;
1140         default:
1141                 return CONNECTION_ERROR_INVALID_PARAMETER;
1142         }
1143
1144 #if defined TIZEN_DUALSIM_ENABLE
1145         rv = vconf_get_int(VCONF_TELEPHONY_DEFAULT_DATA_SERVICE, &sim_id);
1146         if (rv != VCONF_OK) {
1147                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get default subscriber id");
1148                 *llsize = 0;
1149                 return CONNECTION_ERROR_OPERATION_FAILED;
1150         }
1151
1152         switch (sim_id) {
1153         case 0:
1154 #endif
1155                 switch (statistics_type) {
1156                 case CONNECTION_STATISTICS_TYPE_LAST_SENT_DATA:
1157                         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_SNT, &last_size);
1158                         break;
1159                 case CONNECTION_STATISTICS_TYPE_LAST_RECEIVED_DATA:
1160                         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_RCV, &last_size);
1161                         break;
1162                 case CONNECTION_STATISTICS_TYPE_TOTAL_SENT_DATA:
1163                         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_SNT, &last_size);
1164                         rv1 = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_SNT, &size);
1165                         break;
1166                 case CONNECTION_STATISTICS_TYPE_TOTAL_RECEIVED_DATA:
1167                         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_RCV, &last_size);
1168                         rv1 = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_RCV, &size);
1169                         break;
1170                 }
1171 #if defined TIZEN_DUALSIM_ENABLE
1172                 break;
1173         case 1:
1174                 switch (statistics_type) {
1175                 case CONNECTION_STATISTICS_TYPE_LAST_SENT_DATA:
1176                         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_SNT2, &last_size);
1177                         break;
1178                 case CONNECTION_STATISTICS_TYPE_LAST_RECEIVED_DATA:
1179                         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_RCV2, &last_size);
1180                         break;
1181                 case CONNECTION_STATISTICS_TYPE_TOTAL_SENT_DATA:
1182                         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_SNT2, &last_size);
1183                         rv1 = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_SNT2, &size);
1184                         break;
1185                 case CONNECTION_STATISTICS_TYPE_TOTAL_RECEIVED_DATA:
1186                         rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_RCV2, &last_size);
1187                         rv1 = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_RCV2, &size);
1188                         break;
1189                 }
1190                 break;
1191         default:
1192                 *llsize = 0;
1193                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid subscriber id:%d", sim_id);
1194                 return CONNECTION_ERROR_OPERATION_FAILED;
1195         }
1196 #endif
1197
1198         if (rv != VCONF_OK || rv1 != VCONF_OK) {
1199                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get cellular statistics");
1200                 return CONNECTION_ERROR_OPERATION_FAILED;
1201         }
1202
1203         *llsize = (long long)(last_size * 1000) + (long long)(size * 1000);
1204         CONNECTION_LOG(CONNECTION_INFO,"%lld bytes", *llsize);
1205
1206         return CONNECTION_ERROR_NONE;
1207 }
1208
1209 static int __get_statistic(connection_type_e connection_type,
1210                 connection_statistics_type_e statistics_type, long long *llsize)
1211 {
1212         int rv, stat_type;
1213         unsigned long long ull_size;
1214
1215         if (llsize == NULL) {
1216                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1217                 return CONNECTION_ERROR_INVALID_PARAMETER;
1218         }
1219
1220         rv  = _connection_libnet_check_get_privilege();
1221         if (rv == CONNECTION_ERROR_PERMISSION_DENIED)
1222                 return rv;
1223         else if (rv != CONNECTION_ERROR_NONE) {
1224                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get statistics");
1225                 return CONNECTION_ERROR_OPERATION_FAILED;
1226         }
1227
1228         if (connection_type == CONNECTION_TYPE_CELLULAR)
1229                 return __get_cellular_statistic(statistics_type, llsize);
1230         else if (connection_type == CONNECTION_TYPE_WIFI) {
1231                 switch (statistics_type) {
1232                 case CONNECTION_STATISTICS_TYPE_LAST_SENT_DATA:
1233                         stat_type = NET_STATISTICS_TYPE_LAST_SENT_DATA;
1234                         break;
1235                 case CONNECTION_STATISTICS_TYPE_LAST_RECEIVED_DATA:
1236                         stat_type = NET_STATISTICS_TYPE_LAST_RECEIVED_DATA;
1237                         break;
1238                 case CONNECTION_STATISTICS_TYPE_TOTAL_SENT_DATA:
1239                         stat_type = NET_STATISTICS_TYPE_TOTAL_SENT_DATA;
1240                         break;
1241                 case CONNECTION_STATISTICS_TYPE_TOTAL_RECEIVED_DATA:
1242                         stat_type = NET_STATISTICS_TYPE_TOTAL_RECEIVED_DATA;
1243                         break;
1244                 default:
1245                         return CONNECTION_ERROR_INVALID_PARAMETER;
1246                 }
1247
1248                 rv  = _connection_libnet_get_statistics(stat_type, &ull_size);
1249                 if (rv == CONNECTION_ERROR_PERMISSION_DENIED)
1250                         return rv;
1251                 else if (rv != CONNECTION_ERROR_NONE) {
1252                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to get Wi-Fi statistics");
1253                         *llsize = 0;
1254                         return CONNECTION_ERROR_OPERATION_FAILED;
1255                 }
1256
1257                 CONNECTION_LOG(CONNECTION_INFO,"%lld bytes", ull_size);
1258                 *llsize = (long long)ull_size;
1259         } else
1260                 return CONNECTION_ERROR_INVALID_PARAMETER;
1261
1262         return CONNECTION_ERROR_NONE;
1263 }
1264
1265 static int __reset_statistic(connection_type_e connection_type,
1266                 connection_statistics_type_e statistics_type)
1267 {
1268         int conn_type;
1269         int stat_type;
1270         int rv;
1271
1272         if (connection_type == CONNECTION_TYPE_CELLULAR)
1273                 conn_type = NET_DEVICE_CELLULAR;
1274         else if (connection_type == CONNECTION_TYPE_WIFI)
1275                 conn_type = NET_DEVICE_WIFI;
1276         else
1277                 return CONNECTION_ERROR_INVALID_PARAMETER;
1278
1279         switch (statistics_type) {
1280         case CONNECTION_STATISTICS_TYPE_LAST_SENT_DATA:
1281                 stat_type = NET_STATISTICS_TYPE_LAST_SENT_DATA;
1282                 break;
1283         case CONNECTION_STATISTICS_TYPE_LAST_RECEIVED_DATA:
1284                 stat_type = NET_STATISTICS_TYPE_LAST_RECEIVED_DATA;
1285                 break;
1286         case CONNECTION_STATISTICS_TYPE_TOTAL_SENT_DATA:
1287                 stat_type = NET_STATISTICS_TYPE_TOTAL_SENT_DATA;
1288                 break;
1289         case CONNECTION_STATISTICS_TYPE_TOTAL_RECEIVED_DATA:
1290                 stat_type = NET_STATISTICS_TYPE_TOTAL_RECEIVED_DATA;
1291                 break;
1292         default:
1293                 return CONNECTION_ERROR_INVALID_PARAMETER;
1294         }
1295
1296         rv = _connection_libnet_set_statistics(conn_type, stat_type);
1297         if (rv != CONNECTION_ERROR_NONE)
1298                 return rv;
1299
1300         CONNECTION_LOG(CONNECTION_INFO,"connection_reset_statistics success");
1301
1302         return CONNECTION_ERROR_NONE;
1303 }
1304
1305 EXPORT_API int connection_get_statistics(connection_h connection,
1306                                 connection_type_e connection_type,
1307                                 connection_statistics_type_e statistics_type, long long* size)
1308 {
1309         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE);
1310
1311         if(connection_type == CONNECTION_TYPE_CELLULAR )
1312                 CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE);
1313         else if(connection_type == CONNECTION_TYPE_WIFI)
1314                 CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
1315
1316         if (!(__connection_check_handle_validity(connection)) || size == NULL) {
1317                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1318                 return CONNECTION_ERROR_INVALID_PARAMETER;
1319         }
1320
1321         return __get_statistic(connection_type, statistics_type, size);
1322 }
1323
1324 EXPORT_API int connection_reset_statistics(connection_h connection,
1325                                 connection_type_e connection_type,
1326                                 connection_statistics_type_e statistics_type)
1327 {
1328         CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE, WIFI_FEATURE);
1329
1330         if(connection_type == CONNECTION_TYPE_CELLULAR )
1331                 CHECK_FEATURE_SUPPORTED(TELEPHONY_FEATURE);
1332         else if(connection_type == CONNECTION_TYPE_WIFI)
1333                 CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
1334
1335         if (!__connection_check_handle_validity(connection)) {
1336                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1337                 return CONNECTION_ERROR_INVALID_PARAMETER;
1338         }
1339
1340         return __reset_statistic(connection_type, statistics_type);
1341 }
1342