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