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