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