Add doc file
[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 <stdio.h>
18 #include <string.h>
19 #include <glib.h>
20 #include <vconf/vconf.h>
21 #include "net_connection_private.h"
22
23 static GSList *conn_handle_list = NULL;
24
25 static void __connection_cb_state_change_cb(keynode_t *node, void *user_data);
26 static void __connection_cb_ip_change_cb(keynode_t *node, void *user_data);
27 static void __connection_cb_proxy_change_cb(keynode_t *node, void *user_data);
28
29 static int __connection_convert_net_state(int status)
30 {
31         switch (status) {
32         case VCONFKEY_NETWORK_CELLULAR:
33                 return CONNECTION_TYPE_CELLULAR;
34         case VCONFKEY_NETWORK_WIFI:
35                 return CONNECTION_TYPE_WIFI;
36         case VCONFKEY_NETWORK_ETHERNET:
37                 return CONNECTION_TYPE_ETHERNET;
38         case VCONFKEY_NETWORK_BLUETOOTH:
39                 return CONNECTION_TYPE_BT;
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 int __connection_get_type_changed_callback_count(void)
62 {
63         GSList *list;
64         int count = 0;
65
66         for (list = conn_handle_list; list; list = list->next) {
67                 connection_handle_s *local_handle = (connection_handle_s *)list->data;
68                 if (local_handle->type_changed_callback) count++;
69         }
70
71         return count;
72 }
73
74 static int __connection_get_ip_changed_callback_count(void)
75 {
76         GSList *list;
77         int count = 0;
78
79         for (list = conn_handle_list; list; list = list->next) {
80                 connection_handle_s *local_handle = (connection_handle_s *)list->data;
81                 if (local_handle->ip_changed_callback) count++;
82         }
83
84         return count;
85 }
86
87 static int __connection_get_proxy_changed_callback_count(void)
88 {
89         GSList *list;
90         int count = 0;
91
92         for (list = conn_handle_list; list; list = list->next) {
93                 connection_handle_s *local_handle = (connection_handle_s *)list->data;
94                 if (local_handle->proxy_changed_callback) count++;
95         }
96
97         return count;
98 }
99
100 static void __connection_cb_ethernet_cable_state_changed_cb(connection_ethernet_cable_state_e state)
101 {
102         CONNECTION_LOG(CONNECTION_INFO, "Ethernet Cable state Indication");
103
104         GSList *list;
105
106         for (list = conn_handle_list; list; list = list->next) {
107                 connection_handle_s *local_handle = (connection_handle_s *)list->data;
108                 if (local_handle->ethernet_cable_state_changed_callback)
109                         local_handle->ethernet_cable_state_changed_callback(state,
110                                         local_handle->ethernet_cable_state_changed_user_data);
111         }
112 }
113
114 static int __connection_get_ethernet_cable_state_changed_callback_count(void)
115 {
116         GSList *list;
117         int count = 0;
118
119         for (list = conn_handle_list; list; list = list->next) {
120                 connection_handle_s *local_handle = (connection_handle_s *)list->data;
121                 if (local_handle->ethernet_cable_state_changed_callback) count++;
122         }
123
124         return count;
125 }
126
127 static int __connection_set_type_changed_callback(connection_h connection,
128                                                         void *callback, void *user_data)
129 {
130         connection_handle_s *local_handle = (connection_handle_s *)connection;
131
132         if (callback) {
133                 if (__connection_get_type_changed_callback_count() == 0)
134                         if (vconf_notify_key_changed(VCONFKEY_NETWORK_STATUS ,
135                                         __connection_cb_state_change_cb, NULL))
136                                 return CONNECTION_ERROR_OPERATION_FAILED;
137
138                 local_handle->type_changed_user_data = user_data;
139         } else {
140                 if (local_handle->type_changed_callback &&
141                     __connection_get_type_changed_callback_count() == 1)
142                         if (vconf_ignore_key_changed(VCONFKEY_NETWORK_STATUS,
143                                         __connection_cb_state_change_cb))
144                                 return CONNECTION_ERROR_OPERATION_FAILED;
145         }
146
147         local_handle->type_changed_callback = callback;
148         return CONNECTION_ERROR_NONE;
149 }
150
151 static int __connection_set_ip_changed_callback(connection_h connection,
152                                                         void *callback, void *user_data)
153 {
154         connection_handle_s *local_handle = (connection_handle_s *)connection;
155
156         if (callback) {
157                 if (__connection_get_ip_changed_callback_count() == 0)
158                         if (vconf_notify_key_changed(VCONFKEY_NETWORK_IP,
159                                         __connection_cb_ip_change_cb, NULL))
160                                 return CONNECTION_ERROR_OPERATION_FAILED;
161
162                 local_handle->ip_changed_user_data = user_data;
163         } else {
164                 if (local_handle->ip_changed_callback &&
165                     __connection_get_ip_changed_callback_count() == 1)
166                         if (vconf_ignore_key_changed(VCONFKEY_NETWORK_IP,
167                                         __connection_cb_ip_change_cb))
168                                 return CONNECTION_ERROR_OPERATION_FAILED;
169         }
170
171         local_handle->ip_changed_callback = callback;
172         return CONNECTION_ERROR_NONE;
173 }
174
175 static int __connection_set_proxy_changed_callback(connection_h connection,
176                                                         void *callback, void *user_data)
177 {
178         connection_handle_s *local_handle = (connection_handle_s *)connection;
179
180         if (callback) {
181                 if (__connection_get_proxy_changed_callback_count() == 0)
182                         if (vconf_notify_key_changed(VCONFKEY_NETWORK_PROXY,
183                                         __connection_cb_proxy_change_cb, NULL))
184                                 return CONNECTION_ERROR_OPERATION_FAILED;
185
186                 local_handle->proxy_changed_user_data = user_data;
187         } else {
188                 if (local_handle->proxy_changed_callback &&
189                     __connection_get_proxy_changed_callback_count() == 1)
190                         if (vconf_ignore_key_changed(VCONFKEY_NETWORK_PROXY,
191                                         __connection_cb_proxy_change_cb))
192                                 return CONNECTION_ERROR_OPERATION_FAILED;
193         }
194
195         local_handle->proxy_changed_callback = callback;
196         return CONNECTION_ERROR_NONE;
197 }
198
199 static void __connection_cb_state_change_cb(keynode_t *node, void *user_data)
200 {
201         CONNECTION_LOG(CONNECTION_INFO, "Net Status Changed Indication\n");
202
203         GSList *list;
204         int state = vconf_keynode_get_int(node);
205
206         for (list = conn_handle_list; list; list = list->next) {
207                 connection_handle_s *local_handle = (connection_handle_s *)list->data;
208                 if (local_handle->type_changed_callback)
209                         local_handle->type_changed_callback(
210                                         __connection_convert_net_state(state),
211                                         local_handle->type_changed_user_data);
212         }
213 }
214
215 static void __connection_cb_ip_change_cb(keynode_t *node, void *user_data)
216 {
217         CONNECTION_LOG(CONNECTION_INFO, "Net IP Changed Indication\n");
218
219         GSList *list;
220         char *ip_addr = vconf_keynode_get_str(node);
221
222         for (list = conn_handle_list; list; list = list->next) {
223                 connection_handle_s *local_handle = (connection_handle_s *)list->data;
224                 if (local_handle->ip_changed_callback)
225                         local_handle->ip_changed_callback(
226                                         ip_addr, NULL,
227                                         local_handle->ip_changed_user_data);
228         }
229 }
230
231 static void __connection_cb_proxy_change_cb(keynode_t *node, void *user_data)
232 {
233         CONNECTION_LOG(CONNECTION_INFO, "Net IP Changed Indication\n");
234
235         GSList *list;
236         char *proxy = vconf_keynode_get_str(node);
237
238         for (list = conn_handle_list; list; list = list->next) {
239                 connection_handle_s *local_handle = (connection_handle_s *)list->data;
240                 if (local_handle->proxy_changed_callback)
241                         local_handle->proxy_changed_callback(
242                                         proxy, NULL,
243                                         local_handle->proxy_changed_user_data);
244         }
245 }
246
247 static bool __connection_check_handle_validity(connection_h connection)
248 {
249         bool ret = false;
250
251         if (connection == NULL)
252                 return false;
253
254         if (g_slist_find(conn_handle_list, connection) != NULL)
255                 ret = true;
256
257         return ret;
258 }
259
260 static int __connection_set_ethernet_cable_state_changed_cb(connection_h connection,
261                 connection_ethernet_cable_state_chaged_cb callback, void *user_data)
262 {
263         connection_handle_s *local_handle = (connection_handle_s *)connection;
264
265         if (callback) {
266                 if (__connection_get_ethernet_cable_state_changed_callback_count() == 0)
267                         _connection_libnet_set_ethernet_cable_state_changed_cb(
268                                         __connection_cb_ethernet_cable_state_changed_cb);
269
270         } else {
271                 if (__connection_get_ethernet_cable_state_changed_callback_count() == 1)
272                         _connection_libnet_set_ethernet_cable_state_changed_cb(NULL);
273         }
274
275         local_handle->ethernet_cable_state_changed_callback = callback;
276         local_handle->ethernet_cable_state_changed_user_data = user_data;
277         return CONNECTION_ERROR_NONE;
278 }
279
280 static int __connection_get_handle_count(void)
281 {
282         GSList *list;
283         int count = 0;
284
285         if (!conn_handle_list)
286                 return count;
287
288         for (list = conn_handle_list; list; list = list->next) count++;
289
290         return count;
291 }
292
293 /* Connection Manager ********************************************************/
294 EXPORT_API int connection_create(connection_h* connection)
295 {
296         CONNECTION_MUTEX_LOCK;
297         int rv;
298         if (connection == NULL || __connection_check_handle_validity(*connection)) {
299                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
300                 CONNECTION_MUTEX_UNLOCK;
301                 return CONNECTION_ERROR_INVALID_PARAMETER;
302         }
303
304         rv = _connection_libnet_init();
305         if (rv == NET_ERR_ACCESS_DENIED) {
306                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
307                 CONNECTION_MUTEX_UNLOCK;
308                 return CONNECTION_ERROR_PERMISSION_DENIED;
309         }
310         else if (rv != NET_ERR_NONE) {
311                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to create connection[%d]", rv);
312                 CONNECTION_MUTEX_UNLOCK;
313                 return CONNECTION_ERROR_OPERATION_FAILED;
314         }
315
316         *connection = g_try_malloc0(sizeof(connection_handle_s));
317         if (*connection != NULL) {
318                 CONNECTION_LOG(CONNECTION_INFO, "New Handle Created %p\n", *connection);
319         } else {
320                 CONNECTION_MUTEX_UNLOCK;
321                 return CONNECTION_ERROR_OUT_OF_MEMORY;
322         }
323
324         conn_handle_list = g_slist_append(conn_handle_list, *connection);
325
326         CONNECTION_MUTEX_UNLOCK;
327         return CONNECTION_ERROR_NONE;
328 }
329
330 EXPORT_API int connection_destroy(connection_h connection)
331 {
332         CONNECTION_MUTEX_LOCK;
333
334         if (connection == NULL || !(__connection_check_handle_validity(connection))) {
335                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
336                 CONNECTION_MUTEX_UNLOCK;
337                 return CONNECTION_ERROR_INVALID_PARAMETER;
338         }
339
340         CONNECTION_LOG(CONNECTION_INFO, "Destroy Handle : %p\n", connection);
341
342         __connection_set_type_changed_callback(connection, NULL, NULL);
343         __connection_set_ip_changed_callback(connection, NULL, NULL);
344         __connection_set_proxy_changed_callback(connection, NULL, NULL);
345         __connection_set_ethernet_cable_state_changed_cb(connection, NULL, NULL);
346
347         conn_handle_list = g_slist_remove(conn_handle_list, connection);
348
349         g_free(connection);
350
351         if (__connection_get_handle_count() == 0)
352                 _connection_libnet_deinit();
353
354         CONNECTION_MUTEX_UNLOCK;
355         return CONNECTION_ERROR_NONE;
356 }
357
358 EXPORT_API int connection_get_type(connection_h connection, connection_type_e* type)
359 {
360         int status = 0;
361
362         if (type == NULL || !(__connection_check_handle_validity(connection))) {
363                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
364                 return CONNECTION_ERROR_INVALID_PARAMETER;
365         }
366
367         if (vconf_get_int(VCONFKEY_NETWORK_STATUS, &status)) {
368                 CONNECTION_LOG(CONNECTION_ERROR, "vconf_get_int Failed = %d\n", status);
369                 return CONNECTION_ERROR_OPERATION_FAILED;
370         }
371
372         CONNECTION_LOG(CONNECTION_INFO, "Connected Network = %d\n", status);
373
374         *type = __connection_convert_net_state(status);
375
376         return CONNECTION_ERROR_NONE;
377 }
378
379 EXPORT_API int connection_get_ip_address(connection_h connection,
380                                          connection_address_family_e address_family, char **ip_address)
381 {
382         if (ip_address == NULL || !(__connection_check_handle_validity(connection))) {
383                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
384                 return CONNECTION_ERROR_INVALID_PARAMETER;
385         }
386
387         switch (address_family) {
388         case CONNECTION_ADDRESS_FAMILY_IPV4:
389         case CONNECTION_ADDRESS_FAMILY_IPV6:
390                 *ip_address = vconf_get_str(VCONFKEY_NETWORK_IP);
391                 break;
392
393         default:
394                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
395                 return CONNECTION_ERROR_INVALID_PARAMETER;
396         }
397
398         if (*ip_address == NULL) {
399                 CONNECTION_LOG(CONNECTION_ERROR, "vconf_get_str Failed");
400                 return CONNECTION_ERROR_OPERATION_FAILED;
401         }
402
403         return CONNECTION_ERROR_NONE;
404 }
405
406 EXPORT_API int connection_get_proxy(connection_h connection,
407                                     connection_address_family_e address_family, char **proxy)
408 {
409         if (proxy == NULL || !(__connection_check_handle_validity(connection))) {
410                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
411                 return CONNECTION_ERROR_INVALID_PARAMETER;
412         }
413
414         switch (address_family) {
415         case CONNECTION_ADDRESS_FAMILY_IPV4:
416         case CONNECTION_ADDRESS_FAMILY_IPV6:
417                 *proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY);
418                 break;
419
420         default:
421                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
422                 return CONNECTION_ERROR_INVALID_PARAMETER;
423         }
424
425         if (*proxy == NULL) {
426                 CONNECTION_LOG(CONNECTION_ERROR, "vconf_get_str Failed");
427                 return CONNECTION_ERROR_OPERATION_FAILED;
428         }
429
430         return CONNECTION_ERROR_NONE;
431 }
432
433 EXPORT_API int connection_get_mac_address(connection_h connection, connection_type_e type, char** mac_addr)
434 {
435         FILE *fp;
436         char buf[CONNECTION_MAC_INFO_LENGTH + 1];
437
438         if (mac_addr == NULL || !(__connection_check_handle_validity(connection))) {
439                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
440                 return CONNECTION_ERROR_INVALID_PARAMETER;
441         }
442
443         switch (type) {
444         case CONNECTION_TYPE_WIFI:
445                 fp = fopen(WIFI_MAC_INFO_FILE, "r");
446                 if (fp == NULL) {
447                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to open file %s", WIFI_MAC_INFO_FILE);
448                         return CONNECTION_ERROR_OUT_OF_MEMORY;
449                 }
450
451                 if (fgets(buf, sizeof(buf), fp) == NULL) {
452                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to get MAC info from %s", WIFI_MAC_INFO_FILE);
453                         fclose(fp);
454                         return CONNECTION_ERROR_OPERATION_FAILED;
455                 }
456
457                 CONNECTION_LOG(CONNECTION_INFO, "%s : %s", WIFI_MAC_INFO_FILE, buf);
458
459                 *mac_addr = (char *)malloc(CONNECTION_MAC_INFO_LENGTH + 1);
460                 if (*mac_addr == NULL) {
461                         CONNECTION_LOG(CONNECTION_ERROR, "malloc() failed");
462                         fclose(fp);
463                         return CONNECTION_ERROR_OUT_OF_MEMORY;
464                 }
465                 g_strlcpy(*mac_addr, buf, CONNECTION_MAC_INFO_LENGTH + 1);
466                 fclose(fp);
467                 break;
468         case CONNECTION_TYPE_ETHERNET:
469                 fp = fopen(ETHERNET_MAC_INFO_FILE, "r");
470                 if (fp == NULL) {
471                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to open file %s", ETHERNET_MAC_INFO_FILE);
472                         return CONNECTION_ERROR_OUT_OF_MEMORY;
473                 }
474
475                 if (fgets(buf, sizeof(buf), fp) == NULL) {
476                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to get MAC info from %s", ETHERNET_MAC_INFO_FILE);
477                         fclose(fp);
478                         return CONNECTION_ERROR_OPERATION_FAILED;
479                 }
480
481                 CONNECTION_LOG(CONNECTION_INFO, "%s : %s", ETHERNET_MAC_INFO_FILE, buf);
482
483                 *mac_addr = (char *)malloc(CONNECTION_MAC_INFO_LENGTH + 1);
484                 if (*mac_addr == NULL) {
485                         CONNECTION_LOG(CONNECTION_ERROR, "malloc() failed");
486                         fclose(fp);
487                         return CONNECTION_ERROR_OUT_OF_MEMORY;
488                 }
489
490                 g_strlcpy(*mac_addr, buf,CONNECTION_MAC_INFO_LENGTH + 1);
491                 fclose(fp);
492
493                 break;
494         default:
495                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
496                 return CONNECTION_ERROR_INVALID_PARAMETER;
497         }
498
499         /* Checking Invalid MAC Address */
500         if((strcmp(*mac_addr, "00:00:00:00:00:00") == 0) ||
501                         (strcmp(*mac_addr, "ff:ff:ff:ff:ff:ff") == 0)) {
502                 CONNECTION_LOG(CONNECTION_ERROR, "MAC Address(%s) is invalid", *mac_addr);
503                 return CONNECTION_ERROR_INVALID_OPERATION;
504         }
505
506         CONNECTION_LOG(CONNECTION_INFO, "MAC Address %s", *mac_addr);
507
508         return CONNECTION_ERROR_NONE;
509 }
510
511 EXPORT_API int connection_get_cellular_state(connection_h connection, connection_cellular_state_e* state)
512 {
513         int status = 0;
514         int cellular_state = 0;
515
516         if (state == NULL || !(__connection_check_handle_validity(connection))) {
517                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
518                 return CONNECTION_ERROR_INVALID_PARAMETER;
519         }
520
521         if (!vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &status)) {
522                 CONNECTION_LOG(CONNECTION_INFO, "Cellular = %d\n", status);
523                 *state = __connection_convert_cellular_state(status);
524
525                 if (*state == CONNECTION_CELLULAR_STATE_AVAILABLE) {
526                         if (vconf_get_int(VCONFKEY_DNET_STATE, &cellular_state)) {
527                                 CONNECTION_LOG(CONNECTION_ERROR,
528                                                 "vconf_get_int Failed = %d\n", cellular_state);
529                                 return CONNECTION_ERROR_OPERATION_FAILED;
530                         }
531                 }
532
533                 CONNECTION_LOG(CONNECTION_INFO, "Connection state = %d\n", cellular_state);
534
535                 if (cellular_state == VCONFKEY_DNET_NORMAL_CONNECTED ||
536                     cellular_state == VCONFKEY_DNET_SECURE_CONNECTED ||
537                     cellular_state == VCONFKEY_DNET_TRANSFER)
538                         *state = CONNECTION_CELLULAR_STATE_CONNECTED;
539
540                 return CONNECTION_ERROR_NONE;
541         } else {
542                 CONNECTION_LOG(CONNECTION_ERROR, "vconf_get_int Failed = %d\n", status);
543                 return CONNECTION_ERROR_OPERATION_FAILED;
544         }
545 }
546
547 EXPORT_API int connection_get_wifi_state(connection_h connection, connection_wifi_state_e* state)
548 {
549         int rv;
550
551         if (state == NULL || !(__connection_check_handle_validity(connection))) {
552                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
553                 return CONNECTION_ERROR_INVALID_PARAMETER;
554         }
555
556         rv = _connection_libnet_get_wifi_state(state);
557         if (rv != CONNECTION_ERROR_NONE) {
558                 CONNECTION_LOG(CONNECTION_ERROR, "Fail to get Wi-Fi state[%d]", rv);
559                 return rv;
560         }
561
562         CONNECTION_LOG(CONNECTION_INFO, "WiFi state = %d\n", *state);
563
564         return CONNECTION_ERROR_NONE;
565 }
566
567 EXPORT_API int connection_get_ethernet_state(connection_h connection, connection_ethernet_state_e* state)
568 {
569         if (state == NULL || !(__connection_check_handle_validity(connection))) {
570                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
571                 return CONNECTION_ERROR_INVALID_PARAMETER;
572         }
573
574         return _connection_libnet_get_ethernet_state(state);
575 }
576
577 EXPORT_API int connection_get_ethernet_cable_state(connection_h connection, connection_ethernet_cable_state_e *state)
578 {
579         if (state == NULL || !(__connection_check_handle_validity(connection))) {
580                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
581                 return CONNECTION_ERROR_INVALID_PARAMETER;
582         }
583
584         return _connection_libnet_get_ethernet_cable_state(state);
585 }
586
587 EXPORT_API int connection_set_ethernet_cable_state_chaged_cb(connection_h connection,
588                           connection_ethernet_cable_state_chaged_cb callback, void *user_data)
589 {
590         if (callback == NULL || !(__connection_check_handle_validity(connection))) {
591                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
592                 return CONNECTION_ERROR_INVALID_PARAMETER;
593         }
594
595         return __connection_set_ethernet_cable_state_changed_cb(connection,
596                                                         callback, user_data);
597 }
598
599 EXPORT_API int connection_unset_ethernet_cable_state_chaged_cb(connection_h connection)
600 {
601         if ( !(__connection_check_handle_validity(connection)) ) {
602                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
603                 return CONNECTION_ERROR_INVALID_PARAMETER;
604         }
605
606         return __connection_set_ethernet_cable_state_changed_cb(connection,
607                                                         NULL, NULL);
608 }
609
610 EXPORT_API int connection_get_bt_state(connection_h connection, connection_bt_state_e* state)
611 {
612         if (state == NULL || !(__connection_check_handle_validity(connection))) {
613                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
614                 return CONNECTION_ERROR_INVALID_PARAMETER;
615         }
616
617         return _connection_libnet_get_bluetooth_state(state);
618
619 }
620
621 EXPORT_API int connection_set_type_changed_cb(connection_h connection,
622                                         connection_type_changed_cb callback, void* user_data)
623 {
624         if (callback == NULL || !(__connection_check_handle_validity(connection))) {
625                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
626                 return CONNECTION_ERROR_INVALID_PARAMETER;
627         }
628
629         return __connection_set_type_changed_callback(connection, callback, user_data);
630 }
631
632 EXPORT_API int connection_unset_type_changed_cb(connection_h connection)
633 {
634         if (!(__connection_check_handle_validity(connection))) {
635                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
636                 return CONNECTION_ERROR_INVALID_PARAMETER;
637         }
638
639         return __connection_set_type_changed_callback(connection, NULL, NULL);
640 }
641
642 EXPORT_API int connection_set_ip_address_changed_cb(connection_h connection,
643                                 connection_address_changed_cb callback, void* user_data)
644 {
645         if (callback == NULL || !(__connection_check_handle_validity(connection))) {
646                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
647                 return CONNECTION_ERROR_INVALID_PARAMETER;
648         }
649
650         return __connection_set_ip_changed_callback(connection, callback, user_data);
651 }
652
653 EXPORT_API int connection_unset_ip_address_changed_cb(connection_h connection)
654 {
655         if (!(__connection_check_handle_validity(connection))) {
656                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
657                 return CONNECTION_ERROR_INVALID_PARAMETER;
658         }
659
660         return __connection_set_ip_changed_callback(connection, NULL, NULL);
661 }
662
663 EXPORT_API int connection_set_proxy_address_changed_cb(connection_h connection,
664                                 connection_address_changed_cb callback, void* user_data)
665 {
666         if (callback == NULL || !(__connection_check_handle_validity(connection))) {
667                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
668                 return CONNECTION_ERROR_INVALID_PARAMETER;
669         }
670
671         return __connection_set_proxy_changed_callback(connection, callback, user_data);
672 }
673
674 EXPORT_API int connection_unset_proxy_address_changed_cb(connection_h connection)
675 {
676         if (!(__connection_check_handle_validity(connection))) {
677                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
678                 return CONNECTION_ERROR_INVALID_PARAMETER;
679         }
680
681         return __connection_set_proxy_changed_callback(connection, NULL, NULL);
682 }
683
684 EXPORT_API int connection_add_profile(connection_h connection, connection_profile_h profile)
685 {
686         if (!(__connection_check_handle_validity(connection)) ||
687             !(_connection_libnet_check_profile_validity(profile))) {
688                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
689                 return CONNECTION_ERROR_INVALID_PARAMETER;
690         }
691
692         int rv = 0;
693
694         net_profile_info_t *profile_info = profile;
695
696         if (profile_info->profile_type != NET_DEVICE_CELLULAR) {
697                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
698                 return CONNECTION_ERROR_INVALID_PARAMETER;
699         }
700
701         rv = net_add_profile(profile_info->ProfileInfo.Pdp.ServiceType, (net_profile_info_t*)profile);
702         if (rv == NET_ERR_ACCESS_DENIED) {
703                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
704                 return CONNECTION_ERROR_PERMISSION_DENIED;
705         } else if (rv != NET_ERR_NONE) {
706                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to add profile[%d]", rv);
707                 return CONNECTION_ERROR_OPERATION_FAILED;
708         }
709
710         return CONNECTION_ERROR_NONE;
711 }
712
713 EXPORT_API int connection_remove_profile(connection_h connection, connection_profile_h profile)
714 {
715         if (!(__connection_check_handle_validity(connection)) ||
716             !(_connection_libnet_check_profile_validity(profile))) {
717                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
718                 return CONNECTION_ERROR_INVALID_PARAMETER;
719         }
720
721         int rv = 0;
722         net_profile_info_t *profile_info = profile;
723
724         if (profile_info->profile_type != NET_DEVICE_CELLULAR &&
725             profile_info->profile_type != NET_DEVICE_WIFI) {
726                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
727                 return CONNECTION_ERROR_INVALID_PARAMETER;
728         }
729
730         rv = net_delete_profile(profile_info->ProfileName);
731         if (rv == NET_ERR_ACCESS_DENIED) {
732                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
733                 return CONNECTION_ERROR_PERMISSION_DENIED;
734         } else if (rv != NET_ERR_NONE) {
735                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to delete profile[%d]", rv);
736                 return CONNECTION_ERROR_OPERATION_FAILED;
737         }
738
739         return CONNECTION_ERROR_NONE;
740 }
741
742 EXPORT_API int connection_update_profile(connection_h connection, connection_profile_h profile)
743 {
744         if (!(__connection_check_handle_validity(connection)) ||
745             !(_connection_libnet_check_profile_validity(profile))) {
746                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
747                 return CONNECTION_ERROR_INVALID_PARAMETER;
748         }
749
750         int rv = 0;
751         net_profile_info_t *profile_info = profile;
752
753         rv = net_modify_profile(profile_info->ProfileName, (net_profile_info_t*)profile);
754         if (rv == NET_ERR_ACCESS_DENIED) {
755                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
756                 return CONNECTION_ERROR_PERMISSION_DENIED;
757         } else if (rv != NET_ERR_NONE) {
758                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to modify profile[%d]", rv);
759                 return CONNECTION_ERROR_OPERATION_FAILED;
760         }
761
762         return CONNECTION_ERROR_NONE;
763 }
764
765 EXPORT_API int connection_get_profile_iterator(connection_h connection,
766                 connection_iterator_type_e type, connection_profile_iterator_h* profile_iterator)
767 {
768         if (!(__connection_check_handle_validity(connection)) ||
769             (type != CONNECTION_ITERATOR_TYPE_REGISTERED &&
770              type != CONNECTION_ITERATOR_TYPE_CONNECTED &&
771              type != CONNECTION_ITERATOR_TYPE_DEFAULT)) {
772                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
773                 return CONNECTION_ERROR_INVALID_PARAMETER;
774         }
775
776         return _connection_libnet_get_profile_iterator(type, profile_iterator);
777 }
778
779 EXPORT_API int connection_profile_iterator_next(connection_profile_iterator_h profile_iterator,
780                                                         connection_profile_h* profile)
781 {
782         return _connection_libnet_get_iterator_next(profile_iterator, profile);
783 }
784
785 EXPORT_API bool connection_profile_iterator_has_next(connection_profile_iterator_h profile_iterator)
786 {
787         return _connection_libnet_iterator_has_next(profile_iterator);
788 }
789
790 EXPORT_API int connection_destroy_profile_iterator(connection_profile_iterator_h profile_iterator)
791 {
792         return _connection_libnet_destroy_iterator(profile_iterator);
793 }
794
795 EXPORT_API int connection_get_current_profile(connection_h connection, connection_profile_h* profile)
796 {
797         if (!(__connection_check_handle_validity(connection)) || profile == NULL) {
798                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
799                 return CONNECTION_ERROR_INVALID_PARAMETER;
800         }
801
802         return _connection_libnet_get_current_profile(profile);
803 }
804
805 EXPORT_API int connection_get_default_cellular_service_profile(connection_h connection,
806                 connection_cellular_service_type_e type, connection_profile_h* profile)
807 {
808         if (!(__connection_check_handle_validity(connection)) || profile == NULL) {
809                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
810                 return CONNECTION_ERROR_INVALID_PARAMETER;
811         }
812
813         return _connection_libnet_get_cellular_service_profile(type, profile);
814 }
815
816 EXPORT_API int connection_set_default_cellular_service_profile(connection_h connection,
817                 connection_cellular_service_type_e type, connection_profile_h profile)
818 {
819         if (!(__connection_check_handle_validity(connection)) || profile == NULL) {
820                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
821                 return CONNECTION_ERROR_INVALID_PARAMETER;
822         }
823
824         return _connection_libnet_set_cellular_service_profile_sync(type, profile);
825 }
826
827 EXPORT_API int connection_set_default_cellular_service_profile_async(connection_h connection,
828                 connection_cellular_service_type_e type, connection_profile_h profile,
829                 connection_set_default_cb callback, void* user_data)
830 {
831         if (!(__connection_check_handle_validity(connection)) ||
832             profile == NULL || callback == NULL) {
833                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
834                 return CONNECTION_ERROR_INVALID_PARAMETER;
835         }
836
837         return _connection_libnet_set_cellular_service_profile_async(type, profile, callback, user_data);
838 }
839
840 EXPORT_API int connection_open_profile(connection_h connection, connection_profile_h profile,
841                                         connection_opened_cb callback, void* user_data)
842 {
843         if (!(__connection_check_handle_validity(connection)) ||
844             profile == NULL || callback == NULL) {
845                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
846                 return CONNECTION_ERROR_INVALID_PARAMETER;
847         }
848
849         return _connection_libnet_open_profile(profile, callback, user_data);
850 }
851
852 EXPORT_API int connection_close_profile(connection_h connection, connection_profile_h profile,
853                                         connection_closed_cb callback, void* user_data)
854 {
855         if (!(__connection_check_handle_validity(connection)) ||
856             profile == NULL || callback == NULL) {
857                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
858                 return CONNECTION_ERROR_INVALID_PARAMETER;
859         }
860
861         return _connection_libnet_close_profile(profile, callback, user_data);
862 }
863
864 EXPORT_API int connection_reset_profile(connection_h connection,
865                                 connection_reset_option_e type, int id, connection_reset_cb callback, void *user_data)
866 {
867         if (!(__connection_check_handle_validity(connection))) {
868                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed");
869                 return CONNECTION_ERROR_INVALID_PARAMETER;
870         }
871
872         if(id < 0 || id > 1) {
873                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed");
874                 return CONNECTION_ERROR_INVALID_PARAMETER;
875         }
876
877         return _connection_libnet_reset_profile(type, id, callback, user_data);
878 }
879
880 EXPORT_API int connection_add_route(connection_h connection, const char* interface_name, const char* host_address)
881 {
882         if (!(__connection_check_handle_validity(connection)) ||
883             interface_name == NULL || host_address == NULL) {
884                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
885                 return CONNECTION_ERROR_INVALID_PARAMETER;
886         }
887
888         return _connection_libnet_add_route(interface_name, host_address);
889 }
890
891 EXPORT_API int connection_remove_route(connection_h connection, const char* interface_name, const char* host_address)
892 {
893         if (!(__connection_check_handle_validity(connection)) ||
894             interface_name == NULL || host_address == NULL) {
895                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
896                 return CONNECTION_ERROR_INVALID_PARAMETER;
897         }
898
899         return _connection_libnet_remove_route(interface_name, host_address);
900 }
901
902 EXPORT_API int connection_add_route_ipv6(connection_h connection, const char *interface_name, const char *host_address, const char * gateway)
903 {
904         if (!(__connection_check_handle_validity(connection)) ||
905             interface_name == NULL || host_address == NULL) {
906                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
907                 return CONNECTION_ERROR_INVALID_PARAMETER;
908         }
909
910         return _connection_libnet_add_route_ipv6(interface_name, host_address, gateway);
911 }
912
913 EXPORT_API int connection_remove_route_ipv6(connection_h connection, const char *interface_name, const char *host_address, const char * gateway)
914 {
915         if (!(__connection_check_handle_validity(connection)) ||
916             interface_name == NULL || host_address == NULL) {
917                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
918                 return CONNECTION_ERROR_INVALID_PARAMETER;
919         }
920
921         return _connection_libnet_remove_route_ipv6(interface_name, host_address, gateway);
922 }
923
924 /* Connection Statistics module ******************************************************************/
925
926 static int __get_statistic(connection_type_e connection_type,
927                         connection_statistics_type_e statistics_type, long long* llsize)
928 {
929         int rv, size;
930         unsigned long long ull_size;
931         int stat_type;
932         char *key = NULL;
933
934         if (llsize == NULL) {
935                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
936                 return CONNECTION_ERROR_INVALID_PARAMETER;
937         }
938
939         if (connection_type == CONNECTION_TYPE_CELLULAR) {
940                 switch (statistics_type) {
941                 case CONNECTION_STATISTICS_TYPE_LAST_SENT_DATA:
942                         key = VCONFKEY_NETWORK_CELLULAR_PKT_LAST_SNT;
943                         break;
944                 case CONNECTION_STATISTICS_TYPE_LAST_RECEIVED_DATA:
945                         key = VCONFKEY_NETWORK_CELLULAR_PKT_LAST_RCV;
946                         break;
947                 case CONNECTION_STATISTICS_TYPE_TOTAL_SENT_DATA:
948                         key = VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_SNT;
949                         break;
950                 case CONNECTION_STATISTICS_TYPE_TOTAL_RECEIVED_DATA:
951                         key = VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_RCV;
952                         break;
953                 default:
954                         return CONNECTION_ERROR_INVALID_PARAMETER;
955                 }
956
957                 if (vconf_get_int(key, &size)) {
958                         CONNECTION_LOG(CONNECTION_ERROR, "Cannot Get %s = %d\n", key, size);
959                         *llsize = 0;
960                         return CONNECTION_ERROR_OPERATION_FAILED;
961                 }
962
963                 CONNECTION_LOG(CONNECTION_INFO,"%s:%d bytes\n", key, size);
964                 *llsize = (long long)size;
965         } else if (connection_type == CONNECTION_TYPE_WIFI) {
966                 switch (statistics_type) {
967                 case CONNECTION_STATISTICS_TYPE_LAST_SENT_DATA:
968                         stat_type = NET_STATISTICS_TYPE_LAST_SENT_DATA;
969                         break;
970                 case CONNECTION_STATISTICS_TYPE_LAST_RECEIVED_DATA:
971                         stat_type = NET_STATISTICS_TYPE_LAST_RECEIVED_DATA;
972                         break;
973                 case CONNECTION_STATISTICS_TYPE_TOTAL_SENT_DATA:
974                         stat_type = NET_STATISTICS_TYPE_TOTAL_SENT_DATA;
975                         break;
976                 case CONNECTION_STATISTICS_TYPE_TOTAL_RECEIVED_DATA:
977                         stat_type = NET_STATISTICS_TYPE_TOTAL_RECEIVED_DATA;
978                         break;
979                 default:
980                         return CONNECTION_ERROR_INVALID_PARAMETER;
981                 }
982
983                 rv  = _connection_libnet_get_statistics(stat_type, &ull_size);
984                 if (rv == CONNECTION_ERROR_PERMISSION_DENIED)
985                         return rv;
986                 else if (rv != CONNECTION_ERROR_NONE) {
987                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to get Wi-Fi statistics");
988                         *llsize = 0;
989                         return CONNECTION_ERROR_OPERATION_FAILED;
990                 }
991
992                 CONNECTION_LOG(CONNECTION_INFO,"%d bytes\n", ull_size);
993                 *llsize = (long long)ull_size;
994         } else
995                 return CONNECTION_ERROR_INVALID_PARAMETER;
996
997         return CONNECTION_ERROR_NONE;
998 }
999
1000 static int __reset_statistic(connection_type_e connection_type,
1001                         connection_statistics_type_e statistics_type)
1002 {
1003         int conn_type;
1004         int stat_type;
1005         int rv;
1006
1007         if (connection_type == CONNECTION_TYPE_CELLULAR)
1008                 conn_type = NET_DEVICE_CELLULAR;
1009         else if (connection_type == CONNECTION_TYPE_WIFI)
1010                 conn_type = NET_DEVICE_WIFI;
1011         else
1012                 return CONNECTION_ERROR_INVALID_PARAMETER;
1013
1014         switch (statistics_type) {
1015         case CONNECTION_STATISTICS_TYPE_LAST_SENT_DATA:
1016                 stat_type = NET_STATISTICS_TYPE_LAST_SENT_DATA;
1017                 break;
1018         case CONNECTION_STATISTICS_TYPE_LAST_RECEIVED_DATA:
1019                 stat_type = NET_STATISTICS_TYPE_LAST_RECEIVED_DATA;
1020                 break;
1021         case CONNECTION_STATISTICS_TYPE_TOTAL_SENT_DATA:
1022                 stat_type = NET_STATISTICS_TYPE_TOTAL_SENT_DATA;
1023                 break;
1024         case CONNECTION_STATISTICS_TYPE_TOTAL_RECEIVED_DATA:
1025                 stat_type = NET_STATISTICS_TYPE_TOTAL_RECEIVED_DATA;
1026                 break;
1027         default:
1028                 return CONNECTION_ERROR_INVALID_PARAMETER;
1029         }
1030
1031         rv = _connection_libnet_set_statistics(conn_type, stat_type);
1032         if(rv != CONNECTION_ERROR_NONE)
1033                 return rv;
1034
1035
1036         CONNECTION_LOG(CONNECTION_INFO,"connection_reset_statistics success\n");
1037
1038         return CONNECTION_ERROR_NONE;
1039 }
1040
1041 EXPORT_API int connection_get_statistics(connection_h connection,
1042                                 connection_type_e connection_type,
1043                                 connection_statistics_type_e statistics_type, long long* size)
1044 {
1045         if (!(__connection_check_handle_validity(connection)) || size == NULL) {
1046                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1047                 return CONNECTION_ERROR_INVALID_PARAMETER;
1048         }
1049
1050         return __get_statistic(connection_type, statistics_type, size);
1051 }
1052
1053 EXPORT_API int connection_reset_statistics(connection_h connection,
1054                                 connection_type_e connection_type,
1055                                 connection_statistics_type_e statistics_type)
1056 {
1057         if (!(__connection_check_handle_validity(connection))) {
1058                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed");
1059                 return CONNECTION_ERROR_INVALID_PARAMETER;
1060         }
1061
1062         return __reset_statistic(connection_type, statistics_type);
1063 }