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