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