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