Merge "Add test case for ethernet profile" into tizen
[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, "Wrong Parameter Passed\n");
384                 return CONNECTION_ERROR_INVALID_PARAMETER;
385         }
386
387         switch (address_family) {
388         case CONNECTION_ADDRESS_FAMILY_IPV4:
389                 *ip_address = vconf_get_str(VCONFKEY_NETWORK_IP);
390                 break;
391         case CONNECTION_ADDRESS_FAMILY_IPV6:
392                 CONNECTION_LOG(CONNECTION_ERROR, "Not supported yet\n");
393                 return CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED;
394                 break;
395         default:
396                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
397                 return CONNECTION_ERROR_INVALID_PARAMETER;
398         }
399
400         if (*ip_address == NULL) {
401                 CONNECTION_LOG(CONNECTION_ERROR, "vconf_get_str Failed\n");
402                 return CONNECTION_ERROR_OPERATION_FAILED;
403         }
404
405         return CONNECTION_ERROR_NONE;
406 }
407
408 EXPORT_API int connection_get_proxy(connection_h connection,
409                                 connection_address_family_e address_family, char** proxy)
410 {
411         if (proxy == NULL || !(__connection_check_handle_validity(connection))) {
412                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
413                 return CONNECTION_ERROR_INVALID_PARAMETER;
414         }
415
416         switch (address_family) {
417         case CONNECTION_ADDRESS_FAMILY_IPV4:
418                 *proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY);
419                 break;
420         case CONNECTION_ADDRESS_FAMILY_IPV6:
421                 CONNECTION_LOG(CONNECTION_ERROR, "Not supported yet\n");
422                 return CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED;
423                 break;
424         default:
425                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
426                 return CONNECTION_ERROR_INVALID_PARAMETER;
427         }
428
429         if (*proxy == NULL) {
430                 CONNECTION_LOG(CONNECTION_ERROR, "vconf_get_str Failed\n");
431                 return CONNECTION_ERROR_OPERATION_FAILED;
432         }
433
434         return CONNECTION_ERROR_NONE;
435 }
436
437 EXPORT_API int connection_get_mac_address(connection_h connection, connection_type_e type, char** mac_addr)
438 {
439         FILE *fp;
440         char buf[CONNECTION_MAC_INFO_LENGTH + 1];
441
442         if (mac_addr == NULL || !(__connection_check_handle_validity(connection))) {
443                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
444                 return CONNECTION_ERROR_INVALID_PARAMETER;
445         }
446
447         switch (type) {
448         case CONNECTION_TYPE_WIFI:
449                 fp = fopen(WIFI_MAC_INFO_FILE, "r");
450                 if (fp == NULL) {
451                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to open file %s", WIFI_MAC_INFO_FILE);
452                         return CONNECTION_ERROR_OUT_OF_MEMORY;
453                 }
454
455                 if (fgets(buf, sizeof(buf), fp) == NULL) {
456                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to get MAC info from %s", WIFI_MAC_INFO_FILE);
457                         fclose(fp);
458                         return CONNECTION_ERROR_OPERATION_FAILED;
459                 }
460
461                 CONNECTION_LOG(CONNECTION_INFO, "%s : %s", WIFI_MAC_INFO_FILE, buf);
462
463                 *mac_addr = (char *)malloc(CONNECTION_MAC_INFO_LENGTH + 1);
464                 if (*mac_addr == NULL) {
465                         CONNECTION_LOG(CONNECTION_ERROR, "malloc() failed");
466                         fclose(fp);
467                         return CONNECTION_ERROR_OUT_OF_MEMORY;
468                 }
469                 g_strlcpy(*mac_addr, buf, CONNECTION_MAC_INFO_LENGTH + 1);
470                 fclose(fp);
471                 break;
472         case CONNECTION_TYPE_ETHERNET:
473                 fp = fopen(ETHERNET_MAC_INFO_FILE, "r");
474                 if (fp == NULL) {
475                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to open file %s", ETHERNET_MAC_INFO_FILE);
476                         return CONNECTION_ERROR_OUT_OF_MEMORY;
477                 }
478
479                 if (fgets(buf, sizeof(buf), fp) == NULL) {
480                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to get MAC info from %s", ETHERNET_MAC_INFO_FILE);
481                         fclose(fp);
482                         return CONNECTION_ERROR_OPERATION_FAILED;
483                 }
484
485                 CONNECTION_LOG(CONNECTION_INFO, "%s : %s", ETHERNET_MAC_INFO_FILE, buf);
486
487                 *mac_addr = (char *)malloc(CONNECTION_MAC_INFO_LENGTH + 1);
488                 if (*mac_addr == NULL) {
489                         CONNECTION_LOG(CONNECTION_ERROR, "malloc() failed");
490                         fclose(fp);
491                         return CONNECTION_ERROR_OUT_OF_MEMORY;
492                 }
493
494                 g_strlcpy(*mac_addr, buf,CONNECTION_MAC_INFO_LENGTH + 1);
495                 fclose(fp);
496
497                 break;
498         default:
499                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
500                 return CONNECTION_ERROR_INVALID_PARAMETER;
501         }
502
503         /* Checking Invalid MAC Address */
504         if((strcmp(*mac_addr, "00:00:00:00:00:00") == 0) ||
505                         (strcmp(*mac_addr, "ff:ff:ff:ff:ff:ff") == 0)) {
506                 CONNECTION_LOG(CONNECTION_ERROR, "MAC Address(%s) is invalid", *mac_addr);
507                 return CONNECTION_ERROR_INVALID_OPERATION;
508         }
509
510         CONNECTION_LOG(CONNECTION_INFO, "MAC Address %s", *mac_addr);
511
512         return CONNECTION_ERROR_NONE;
513 }
514
515 EXPORT_API int connection_get_cellular_state(connection_h connection, connection_cellular_state_e* state)
516 {
517         int status = 0;
518         int cellular_state = 0;
519
520         if (state == NULL || !(__connection_check_handle_validity(connection))) {
521                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
522                 return CONNECTION_ERROR_INVALID_PARAMETER;
523         }
524
525         if (!vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &status)) {
526                 CONNECTION_LOG(CONNECTION_INFO, "Cellular = %d\n", status);
527                 *state = __connection_convert_cellular_state(status);
528
529                 if (*state == CONNECTION_CELLULAR_STATE_AVAILABLE) {
530                         if (vconf_get_int(VCONFKEY_DNET_STATE, &cellular_state)) {
531                                 CONNECTION_LOG(CONNECTION_ERROR,
532                                                 "vconf_get_int Failed = %d\n", cellular_state);
533                                 return CONNECTION_ERROR_OPERATION_FAILED;
534                         }
535                 }
536
537                 CONNECTION_LOG(CONNECTION_INFO, "Connection state = %d\n", cellular_state);
538
539                 if (cellular_state == VCONFKEY_DNET_NORMAL_CONNECTED ||
540                     cellular_state == VCONFKEY_DNET_SECURE_CONNECTED ||
541                     cellular_state == VCONFKEY_DNET_TRANSFER)
542                         *state = CONNECTION_CELLULAR_STATE_CONNECTED;
543
544                 return CONNECTION_ERROR_NONE;
545         } else {
546                 CONNECTION_LOG(CONNECTION_ERROR, "vconf_get_int Failed = %d\n", status);
547                 return CONNECTION_ERROR_OPERATION_FAILED;
548         }
549 }
550
551 EXPORT_API int connection_get_wifi_state(connection_h connection, connection_wifi_state_e* state)
552 {
553         int rv;
554
555         if (state == NULL || !(__connection_check_handle_validity(connection))) {
556                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
557                 return CONNECTION_ERROR_INVALID_PARAMETER;
558         }
559
560         rv = _connection_libnet_get_wifi_state(state);
561         if (rv != CONNECTION_ERROR_NONE) {
562                 CONNECTION_LOG(CONNECTION_ERROR, "Fail to get Wi-Fi state[%d]", rv);
563                 return rv;
564         }
565
566         CONNECTION_LOG(CONNECTION_INFO, "WiFi state = %d\n", *state);
567
568         return CONNECTION_ERROR_NONE;
569 }
570
571 EXPORT_API int connection_get_ethernet_state(connection_h connection, connection_ethernet_state_e* state)
572 {
573         if (state == NULL || !(__connection_check_handle_validity(connection))) {
574                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
575                 return CONNECTION_ERROR_INVALID_PARAMETER;
576         }
577
578         return _connection_libnet_get_ethernet_state(state);
579 }
580
581 EXPORT_API int connection_get_ethernet_cable_state(connection_h connection, connection_ethernet_cable_state_e *state)
582 {
583         if (state == NULL || !(__connection_check_handle_validity(connection))) {
584                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
585                 return CONNECTION_ERROR_INVALID_PARAMETER;
586         }
587
588         return _connection_libnet_get_ethernet_cable_state(state);
589 }
590
591 EXPORT_API int connection_set_ethernet_cable_state_chaged_cb(connection_h connection,
592                           connection_ethernet_cable_state_chaged_cb callback, void *user_data)
593 {
594         if (callback == NULL || !(__connection_check_handle_validity(connection))) {
595                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
596                 return CONNECTION_ERROR_INVALID_PARAMETER;
597         }
598
599         return __connection_set_ethernet_cable_state_changed_cb(connection,
600                                                         callback, user_data);
601 }
602
603 EXPORT_API int connection_unset_ethernet_cable_state_chaged_cb(connection_h connection)
604 {
605         if ( !(__connection_check_handle_validity(connection)) ) {
606                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
607                 return CONNECTION_ERROR_INVALID_PARAMETER;
608         }
609
610         return __connection_set_ethernet_cable_state_changed_cb(connection,
611                                                         NULL, NULL);
612 }
613
614 EXPORT_API int connection_get_bt_state(connection_h connection, connection_bt_state_e* state)
615 {
616         if (state == NULL || !(__connection_check_handle_validity(connection))) {
617                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
618                 return CONNECTION_ERROR_INVALID_PARAMETER;
619         }
620
621         return _connection_libnet_get_bluetooth_state(state);
622
623 }
624
625 EXPORT_API int connection_set_type_changed_cb(connection_h connection,
626                                         connection_type_changed_cb callback, void* user_data)
627 {
628         if (callback == NULL || !(__connection_check_handle_validity(connection))) {
629                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
630                 return CONNECTION_ERROR_INVALID_PARAMETER;
631         }
632
633         return __connection_set_type_changed_callback(connection, callback, user_data);
634 }
635
636 EXPORT_API int connection_unset_type_changed_cb(connection_h connection)
637 {
638         if (!(__connection_check_handle_validity(connection))) {
639                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
640                 return CONNECTION_ERROR_INVALID_PARAMETER;
641         }
642
643         return __connection_set_type_changed_callback(connection, NULL, NULL);
644 }
645
646 EXPORT_API int connection_set_ip_address_changed_cb(connection_h connection,
647                                 connection_address_changed_cb callback, void* user_data)
648 {
649         if (callback == NULL || !(__connection_check_handle_validity(connection))) {
650                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
651                 return CONNECTION_ERROR_INVALID_PARAMETER;
652         }
653
654         return __connection_set_ip_changed_callback(connection, callback, user_data);
655 }
656
657 EXPORT_API int connection_unset_ip_address_changed_cb(connection_h connection)
658 {
659         if (!(__connection_check_handle_validity(connection))) {
660                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
661                 return CONNECTION_ERROR_INVALID_PARAMETER;
662         }
663
664         return __connection_set_ip_changed_callback(connection, NULL, NULL);
665 }
666
667 EXPORT_API int connection_set_proxy_address_changed_cb(connection_h connection,
668                                 connection_address_changed_cb callback, void* user_data)
669 {
670         if (callback == NULL || !(__connection_check_handle_validity(connection))) {
671                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
672                 return CONNECTION_ERROR_INVALID_PARAMETER;
673         }
674
675         return __connection_set_proxy_changed_callback(connection, callback, user_data);
676 }
677
678 EXPORT_API int connection_unset_proxy_address_changed_cb(connection_h connection)
679 {
680         if (!(__connection_check_handle_validity(connection))) {
681                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
682                 return CONNECTION_ERROR_INVALID_PARAMETER;
683         }
684
685         return __connection_set_proxy_changed_callback(connection, NULL, NULL);
686 }
687
688 EXPORT_API int connection_add_profile(connection_h connection, connection_profile_h profile)
689 {
690         if (!(__connection_check_handle_validity(connection)) ||
691             !(_connection_libnet_check_profile_validity(profile))) {
692                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
693                 return CONNECTION_ERROR_INVALID_PARAMETER;
694         }
695
696         int rv = 0;
697
698         net_profile_info_t *profile_info = profile;
699
700         if (profile_info->profile_type != NET_DEVICE_CELLULAR) {
701                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
702                 return CONNECTION_ERROR_INVALID_PARAMETER;
703         }
704
705         rv = net_add_profile(profile_info->ProfileInfo.Pdp.ServiceType, (net_profile_info_t*)profile);
706         if (rv == NET_ERR_ACCESS_DENIED) {
707                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
708                 return CONNECTION_ERROR_PERMISSION_DENIED;
709         } else if (rv != NET_ERR_NONE) {
710                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to add profile[%d]", rv);
711                 return CONNECTION_ERROR_OPERATION_FAILED;
712         }
713
714         return CONNECTION_ERROR_NONE;
715 }
716
717 EXPORT_API int connection_remove_profile(connection_h connection, connection_profile_h profile)
718 {
719         if (!(__connection_check_handle_validity(connection)) ||
720             !(_connection_libnet_check_profile_validity(profile))) {
721                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
722                 return CONNECTION_ERROR_INVALID_PARAMETER;
723         }
724
725         int rv = 0;
726         net_profile_info_t *profile_info = profile;
727
728         if (profile_info->profile_type != NET_DEVICE_CELLULAR &&
729             profile_info->profile_type != NET_DEVICE_WIFI) {
730                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
731                 return CONNECTION_ERROR_INVALID_PARAMETER;
732         }
733
734         rv = net_delete_profile(profile_info->ProfileName);
735         if (rv == NET_ERR_ACCESS_DENIED) {
736                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
737                 return CONNECTION_ERROR_PERMISSION_DENIED;
738         } else if (rv != NET_ERR_NONE) {
739                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to delete profile[%d]", rv);
740                 return CONNECTION_ERROR_OPERATION_FAILED;
741         }
742
743         return CONNECTION_ERROR_NONE;
744 }
745
746 EXPORT_API int connection_update_profile(connection_h connection, connection_profile_h profile)
747 {
748         if (!(__connection_check_handle_validity(connection)) ||
749             !(_connection_libnet_check_profile_validity(profile))) {
750                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
751                 return CONNECTION_ERROR_INVALID_PARAMETER;
752         }
753
754         int rv = 0;
755         net_profile_info_t *profile_info = profile;
756
757         rv = net_modify_profile(profile_info->ProfileName, (net_profile_info_t*)profile);
758         if (rv == NET_ERR_ACCESS_DENIED) {
759                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
760                 return CONNECTION_ERROR_PERMISSION_DENIED;
761         } else if (rv != NET_ERR_NONE) {
762                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to modify profile[%d]", rv);
763                 return CONNECTION_ERROR_OPERATION_FAILED;
764         }
765
766         return CONNECTION_ERROR_NONE;
767 }
768
769 EXPORT_API int connection_get_profile_iterator(connection_h connection,
770                 connection_iterator_type_e type, connection_profile_iterator_h* profile_iterator)
771 {
772         if (!(__connection_check_handle_validity(connection)) ||
773             (type != CONNECTION_ITERATOR_TYPE_REGISTERED &&
774              type != CONNECTION_ITERATOR_TYPE_CONNECTED &&
775              type != CONNECTION_ITERATOR_TYPE_DEFAULT)) {
776                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
777                 return CONNECTION_ERROR_INVALID_PARAMETER;
778         }
779
780         return _connection_libnet_get_profile_iterator(type, profile_iterator);
781 }
782
783 EXPORT_API int connection_profile_iterator_next(connection_profile_iterator_h profile_iterator,
784                                                         connection_profile_h* profile)
785 {
786         return _connection_libnet_get_iterator_next(profile_iterator, profile);
787 }
788
789 EXPORT_API bool connection_profile_iterator_has_next(connection_profile_iterator_h profile_iterator)
790 {
791         return _connection_libnet_iterator_has_next(profile_iterator);
792 }
793
794 EXPORT_API int connection_destroy_profile_iterator(connection_profile_iterator_h profile_iterator)
795 {
796         return _connection_libnet_destroy_iterator(profile_iterator);
797 }
798
799 EXPORT_API int connection_get_current_profile(connection_h connection, connection_profile_h* profile)
800 {
801         if (!(__connection_check_handle_validity(connection)) || profile == NULL) {
802                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
803                 return CONNECTION_ERROR_INVALID_PARAMETER;
804         }
805
806         return _connection_libnet_get_current_profile(profile);
807 }
808
809 EXPORT_API int connection_get_default_cellular_service_profile(connection_h connection,
810                 connection_cellular_service_type_e type, connection_profile_h* profile)
811 {
812         if (!(__connection_check_handle_validity(connection)) || profile == NULL) {
813                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
814                 return CONNECTION_ERROR_INVALID_PARAMETER;
815         }
816
817         return _connection_libnet_get_cellular_service_profile(type, profile);
818 }
819
820 EXPORT_API int connection_set_default_cellular_service_profile(connection_h connection,
821                 connection_cellular_service_type_e type, connection_profile_h profile)
822 {
823         if (!(__connection_check_handle_validity(connection)) || profile == NULL) {
824                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
825                 return CONNECTION_ERROR_INVALID_PARAMETER;
826         }
827
828         return _connection_libnet_set_cellular_service_profile_sync(type, profile);
829 }
830
831 EXPORT_API int connection_set_default_cellular_service_profile_async(connection_h connection,
832                 connection_cellular_service_type_e type, connection_profile_h profile,
833                 connection_set_default_cb callback, void* user_data)
834 {
835         if (!(__connection_check_handle_validity(connection)) ||
836             profile == NULL || callback == NULL) {
837                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
838                 return CONNECTION_ERROR_INVALID_PARAMETER;
839         }
840
841         return _connection_libnet_set_cellular_service_profile_async(type, profile, callback, user_data);
842 }
843
844 EXPORT_API int connection_open_profile(connection_h connection, connection_profile_h profile,
845                                         connection_opened_cb callback, void* user_data)
846 {
847         if (!(__connection_check_handle_validity(connection)) ||
848             profile == NULL || callback == NULL) {
849                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
850                 return CONNECTION_ERROR_INVALID_PARAMETER;
851         }
852
853         return _connection_libnet_open_profile(profile, callback, user_data);
854 }
855
856 EXPORT_API int connection_close_profile(connection_h connection, connection_profile_h profile,
857                                         connection_closed_cb callback, void* user_data)
858 {
859         if (!(__connection_check_handle_validity(connection)) ||
860             profile == NULL || callback == NULL) {
861                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
862                 return CONNECTION_ERROR_INVALID_PARAMETER;
863         }
864
865         return _connection_libnet_close_profile(profile, callback, user_data);
866 }
867
868 EXPORT_API int connection_reset_profile(connection_h connection,
869                                 connection_reset_option_e type, int id, connection_reset_cb callback, void *user_data)
870 {
871         if (!(__connection_check_handle_validity(connection))) {
872                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed");
873                 return CONNECTION_ERROR_INVALID_PARAMETER;
874         }
875
876         if(id < 0 || id > 1) {
877                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed");
878                 return CONNECTION_ERROR_INVALID_PARAMETER;
879         }
880
881         return _connection_libnet_reset_profile(type, id, callback, user_data);
882 }
883
884 EXPORT_API int connection_add_route(connection_h connection, const char* interface_name, const char* host_address)
885 {
886         if (!(__connection_check_handle_validity(connection)) ||
887             interface_name == NULL || host_address == NULL) {
888                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
889                 return CONNECTION_ERROR_INVALID_PARAMETER;
890         }
891
892         return _connection_libnet_add_route(interface_name, host_address);
893 }
894
895 EXPORT_API int connection_remove_route(connection_h connection, const char* interface_name, const char* host_address)
896 {
897         if (!(__connection_check_handle_validity(connection)) ||
898             interface_name == NULL || host_address == NULL) {
899                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
900                 return CONNECTION_ERROR_INVALID_PARAMETER;
901         }
902
903         return _connection_libnet_remove_route(interface_name, host_address);
904 }
905
906 /* Connection Statistics module ******************************************************************/
907
908 static int __get_statistic(connection_type_e connection_type,
909                         connection_statistics_type_e statistics_type, long long* llsize)
910 {
911         int rv, size;
912         unsigned long long ull_size;
913         int stat_type;
914         char *key = NULL;
915
916         if (llsize == NULL) {
917                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed\n");
918                 return CONNECTION_ERROR_INVALID_PARAMETER;
919         }
920
921         if (connection_type == CONNECTION_TYPE_CELLULAR) {
922                 switch (statistics_type) {
923                 case CONNECTION_STATISTICS_TYPE_LAST_SENT_DATA:
924                         key = VCONFKEY_NETWORK_CELLULAR_PKT_LAST_SNT;
925                         break;
926                 case CONNECTION_STATISTICS_TYPE_LAST_RECEIVED_DATA:
927                         key = VCONFKEY_NETWORK_CELLULAR_PKT_LAST_RCV;
928                         break;
929                 case CONNECTION_STATISTICS_TYPE_TOTAL_SENT_DATA:
930                         key = VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_SNT;
931                         break;
932                 case CONNECTION_STATISTICS_TYPE_TOTAL_RECEIVED_DATA:
933                         key = VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_RCV;
934                         break;
935                 default:
936                         return CONNECTION_ERROR_INVALID_PARAMETER;
937                 }
938
939                 if (vconf_get_int(key, &size)) {
940                         CONNECTION_LOG(CONNECTION_ERROR, "Cannot Get %s = %d\n", key, size);
941                         *llsize = 0;
942                         return CONNECTION_ERROR_OPERATION_FAILED;
943                 }
944
945                 CONNECTION_LOG(CONNECTION_INFO,"%s:%d bytes\n", key, size);
946                 *llsize = (long long)size;
947         } else if (connection_type == CONNECTION_TYPE_WIFI) {
948                 switch (statistics_type) {
949                 case CONNECTION_STATISTICS_TYPE_LAST_SENT_DATA:
950                         stat_type = NET_STATISTICS_TYPE_LAST_SENT_DATA;
951                         break;
952                 case CONNECTION_STATISTICS_TYPE_LAST_RECEIVED_DATA:
953                         stat_type = NET_STATISTICS_TYPE_LAST_RECEIVED_DATA;
954                         break;
955                 case CONNECTION_STATISTICS_TYPE_TOTAL_SENT_DATA:
956                         stat_type = NET_STATISTICS_TYPE_TOTAL_SENT_DATA;
957                         break;
958                 case CONNECTION_STATISTICS_TYPE_TOTAL_RECEIVED_DATA:
959                         stat_type = NET_STATISTICS_TYPE_TOTAL_RECEIVED_DATA;
960                         break;
961                 default:
962                         return CONNECTION_ERROR_INVALID_PARAMETER;
963                 }
964
965                 rv  = _connection_libnet_get_statistics(stat_type, &ull_size);
966                 if (rv == CONNECTION_ERROR_PERMISSION_DENIED)
967                         return rv;
968                 else if (rv != CONNECTION_ERROR_NONE) {
969                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to get Wi-Fi statistics");
970                         *llsize = 0;
971                         return CONNECTION_ERROR_OPERATION_FAILED;
972                 }
973
974                 CONNECTION_LOG(CONNECTION_INFO,"%d bytes\n", ull_size);
975                 *llsize = (long long)ull_size;
976         } else
977                 return CONNECTION_ERROR_INVALID_PARAMETER;
978
979         return CONNECTION_ERROR_NONE;
980 }
981
982 static int __reset_statistic(connection_type_e connection_type,
983                         connection_statistics_type_e statistics_type)
984 {
985         int conn_type;
986         int stat_type;
987         int rv;
988
989         if (connection_type == CONNECTION_TYPE_CELLULAR)
990                 conn_type = NET_DEVICE_CELLULAR;
991         else if (connection_type == CONNECTION_TYPE_WIFI)
992                 conn_type = NET_DEVICE_WIFI;
993         else
994                 return CONNECTION_ERROR_INVALID_PARAMETER;
995
996         switch (statistics_type) {
997         case CONNECTION_STATISTICS_TYPE_LAST_SENT_DATA:
998                 stat_type = NET_STATISTICS_TYPE_LAST_SENT_DATA;
999                 break;
1000         case CONNECTION_STATISTICS_TYPE_LAST_RECEIVED_DATA:
1001                 stat_type = NET_STATISTICS_TYPE_LAST_RECEIVED_DATA;
1002                 break;
1003         case CONNECTION_STATISTICS_TYPE_TOTAL_SENT_DATA:
1004                 stat_type = NET_STATISTICS_TYPE_TOTAL_SENT_DATA;
1005                 break;
1006         case CONNECTION_STATISTICS_TYPE_TOTAL_RECEIVED_DATA:
1007                 stat_type = NET_STATISTICS_TYPE_TOTAL_RECEIVED_DATA;
1008                 break;
1009         default:
1010                 return CONNECTION_ERROR_INVALID_PARAMETER;
1011         }
1012
1013         rv = _connection_libnet_set_statistics(conn_type, stat_type);
1014         if(rv != CONNECTION_ERROR_NONE)
1015                 return rv;
1016
1017
1018         CONNECTION_LOG(CONNECTION_INFO,"connection_reset_statistics success\n");
1019
1020         return CONNECTION_ERROR_NONE;
1021 }
1022
1023 EXPORT_API int connection_get_statistics(connection_h connection,
1024                                 connection_type_e connection_type,
1025                                 connection_statistics_type_e statistics_type, long long* size)
1026 {
1027         if (!(__connection_check_handle_validity(connection)) || size == NULL) {
1028                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter");
1029                 return CONNECTION_ERROR_INVALID_PARAMETER;
1030         }
1031
1032         return __get_statistic(connection_type, statistics_type, size);
1033 }
1034
1035 EXPORT_API int connection_reset_statistics(connection_h connection,
1036                                 connection_type_e connection_type,
1037                                 connection_statistics_type_e statistics_type)
1038 {
1039         if (!(__connection_check_handle_validity(connection))) {
1040                 CONNECTION_LOG(CONNECTION_ERROR, "Wrong Parameter Passed");
1041                 return CONNECTION_ERROR_INVALID_PARAMETER;
1042         }
1043
1044         return __reset_statistic(connection_type, statistics_type);
1045 }