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