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