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