Refactoring how to get profile list
[platform/core/api/connection.git] / src / libnetwork.c
1 /*
2  * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <glib.h>
18 #include <stdio.h>
19 #include <stdarg.h>
20 #include <string.h>
21 #include <vconf/vconf.h>
22 #include <system_info.h>
23 #include <arpa/inet.h>
24
25 #include "net_connection_private.h"
26
27 static GSList *prof_handle_list = NULL;
28 static GHashTable *profile_cb_table = NULL;
29 static pthread_mutex_t g_conn_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
30
31 struct _profile_cb_s {
32         connection_profile_state_changed_cb callback;
33         connection_profile_state_e state;
34         void *user_data;
35 };
36
37 struct _profile_list_s {
38         int next;
39         int count;
40         net_profile_info_t *profiles;
41 };
42
43 static struct _profile_list_s profile_iterator = {0, 0, NULL};
44 static bool connection_is_feature_checked[CONNECTION_SUPPORTED_FEATURE_MAX] = {0, };
45 static bool connection_feature_supported[CONNECTION_SUPPORTED_FEATURE_MAX] = {0, };
46
47 //LCOV_EXCL_START
48 static connection_error_e __libnet_convert_to_cp_error_type(net_err_t err_type)
49 {
50         switch (err_type) {
51         case NET_ERR_NONE:
52                 return CONNECTION_ERROR_NONE;
53         case NET_ERR_APP_ALREADY_REGISTERED:
54                 return CONNECTION_ERROR_INVALID_OPERATION;
55         case NET_ERR_APP_NOT_REGISTERED:
56                 return CONNECTION_ERROR_INVALID_OPERATION;
57         case NET_ERR_NO_ACTIVE_CONNECTIONS:
58                 return CONNECTION_ERROR_NO_CONNECTION;
59         case NET_ERR_ACTIVE_CONNECTION_EXISTS:
60                 return CONNECTION_ERROR_ALREADY_EXISTS;
61         case NET_ERR_CONNECTION_DHCP_FAILED:
62                 return CONNECTION_ERROR_DHCP_FAILED;
63         case NET_ERR_CONNECTION_INVALID_KEY:
64                 return CONNECTION_ERROR_INVALID_KEY;
65         case NET_ERR_IN_PROGRESS:
66                 return CONNECTION_ERROR_NOW_IN_PROGRESS;
67         case NET_ERR_OPERATION_ABORTED:
68                 return CONNECTION_ERROR_OPERATION_ABORTED;
69         case NET_ERR_TIME_OUT:
70                 return CONNECTION_ERROR_NO_REPLY;
71         case NET_ERR_ACCESS_DENIED:
72                 return CONNECTION_ERROR_PERMISSION_DENIED;
73         default:
74                 return CONNECTION_ERROR_OPERATION_FAILED;
75         }
76 }
77
78 static const char *__libnet_convert_cp_error_type_to_string(connection_error_e err_type)
79 {
80         switch (err_type) {
81         case CONNECTION_ERROR_NONE:
82                 return "NONE";
83         case CONNECTION_ERROR_INVALID_PARAMETER:
84                 return "INVALID_PARAMETER";
85         case CONNECTION_ERROR_OUT_OF_MEMORY:
86                 return "OUT_OF_MEMORY";
87         case CONNECTION_ERROR_INVALID_OPERATION:
88                 return "INVALID_OPERATION";
89         case CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED:
90                 return "ADDRESS_FAMILY_NOT_SUPPORTED";
91         case CONNECTION_ERROR_OPERATION_FAILED:
92                 return "OPERATION_FAILED";
93         case CONNECTION_ERROR_ITERATOR_END:
94                 return "ITERATOR_END";
95         case CONNECTION_ERROR_NO_CONNECTION:
96                 return "NO_CONNECTION";
97         case CONNECTION_ERROR_NOW_IN_PROGRESS:
98                 return "NOW_IN_PROGRESS";
99         case CONNECTION_ERROR_ALREADY_EXISTS:
100                 return "ALREADY_EXISTS";
101         case CONNECTION_ERROR_OPERATION_ABORTED:
102                 return "OPERATION_ABORTED";
103         case CONNECTION_ERROR_DHCP_FAILED:
104                 return "DHCP_FAILED";
105         case CONNECTION_ERROR_INVALID_KEY:
106                 return "INVALID_KEY";
107         case CONNECTION_ERROR_NO_REPLY:
108                 return "NO_REPLY";
109         case CONNECTION_ERROR_PERMISSION_DENIED:
110                 return "PERMISSION_DENIED";
111         case CONNECTION_ERROR_NOT_SUPPORTED:
112                 return "NOT_SUPPORTED";
113         case CONNECTION_ERROR_ALREADY_INITIALIZED:
114                 return "ALREADY_INITIALIZED";
115         case CONNECTION_ERROR_NOT_INITIALIZED:
116                 return "NOT_INITIALIZED";
117         }
118
119         return "UNKNOWN";
120 }
121
122 static const char *__libnet_convert_cp_state_to_string(connection_profile_state_e state)
123 {
124         switch (state) {
125         case CONNECTION_PROFILE_STATE_DISCONNECTED:
126                 return "DISCONNECTED";
127         case CONNECTION_PROFILE_STATE_ASSOCIATION:
128                 return "ASSOCIATION";
129         case CONNECTION_PROFILE_STATE_CONFIGURATION:
130                 return "CONFIGURATION";
131         case CONNECTION_PROFILE_STATE_CONNECTED:
132                 return "CONNECTED";
133         default:
134                 return "UNKNOWN";
135         }
136 }
137
138 static void __libnet_state_changed_cb(char *profile_name, connection_profile_state_e state)
139 {
140         struct _profile_cb_s *cb_info;
141
142         if (profile_name == NULL)
143                 return;
144
145         cb_info = g_hash_table_lookup(profile_cb_table, profile_name);
146         if (cb_info == NULL)
147                 return;
148
149         if (cb_info->state == state)
150                 return;
151
152         cb_info->state = state;
153
154         if (state < 0 || cb_info->callback == NULL)
155                 return;
156
157         cb_info->callback(cb_info->state, cb_info->user_data);
158 }
159
160 static void __libnet_clear_profile_list(struct _profile_list_s *profile_list)
161 {
162         if (profile_list->count > 0)
163                 g_free(profile_list->profiles);
164
165         profile_list->count = 0;
166         profile_list->next = 0;
167         profile_list->profiles = NULL;
168 }
169
170 static void __libnet_evt_cb(net_event_info_t *event_cb, void *user_data)
171 {
172         bool is_requested = false;
173         connection_error_e result = CONNECTION_ERROR_NONE;
174         connection_handle_s *conn_handle = (connection_handle_s *)user_data;
175
176         switch (event_cb->Event) {
177         case NET_EVENT_OPEN_RSP:
178                 is_requested = true;
179                 /* fall through */
180         case NET_EVENT_OPEN_IND:
181                 result = __libnet_convert_to_cp_error_type(event_cb->Error);
182                 CONNECTION_LOG(CONNECTION_INFO, "Connection opened %s[%s]",
183                                         (is_requested) ? "RSP" : "IND",
184                                         __libnet_convert_cp_error_type_to_string(result));
185
186                 if (is_requested) {
187                         if (conn_handle->opened_callback) {
188                                 conn_handle->opened_callback(result,
189                                         conn_handle->opened_user_data);
190
191                                 conn_handle->opened_callback = NULL;
192                                 conn_handle->opened_user_data = NULL;
193                         }
194                 }
195
196                 switch (event_cb->Error) {
197                 case NET_ERR_NONE:
198                 case NET_ERR_ACTIVE_CONNECTION_EXISTS:
199                         CONNECTION_LOG(CONNECTION_INFO, "Successfully open connection");
200
201                         __libnet_state_changed_cb(event_cb->ProfileName, CONNECTION_PROFILE_STATE_CONNECTED);
202                         return;
203                 default:
204                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to open connection[%s]",
205                                                 __libnet_convert_cp_error_type_to_string(result));
206                 }
207
208                 __libnet_state_changed_cb(event_cb->ProfileName, CONNECTION_PROFILE_STATE_DISCONNECTED);
209
210                 break;
211         case NET_EVENT_CLOSE_RSP:
212                 is_requested = true;
213                 /* fall through */
214         case NET_EVENT_CLOSE_IND:
215                 result = __libnet_convert_to_cp_error_type(event_cb->Error);
216                 CONNECTION_LOG(CONNECTION_INFO, "Connection closed %s[%s]",
217                                         (is_requested) ? "RSP" : "IND",
218                                         __libnet_convert_cp_error_type_to_string(result));
219
220                 if (is_requested) {
221                         if (conn_handle->closed_callback) {
222                                 conn_handle->closed_callback(result,
223                                         conn_handle->closed_user_data);
224
225                                 conn_handle->closed_callback = NULL;
226                                 conn_handle->closed_user_data = NULL;
227                         }
228                 }
229
230                 switch (event_cb->Error) {
231                 case NET_ERR_NONE:
232                         CONNECTION_LOG(CONNECTION_INFO, "Successfully closed connection");
233
234                         __libnet_state_changed_cb(event_cb->ProfileName, CONNECTION_PROFILE_STATE_DISCONNECTED);
235                         return;
236                 default:
237                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to close connection[%s]",
238                                                         __libnet_convert_cp_error_type_to_string(result));
239                 }
240
241                 break;
242         case NET_EVENT_NET_STATE_IND:
243                 CONNECTION_LOG(CONNECTION_INFO, "State changed IND");
244
245                 if (event_cb->Datalength != sizeof(net_state_type_t))
246                         return;
247
248                 net_state_type_t *profile_state = (net_state_type_t *)event_cb->Data;
249                 connection_profile_state_e cp_state = _profile_convert_to_cp_state(*profile_state);
250
251                 CONNECTION_LOG(CONNECTION_INFO, "state: %s", __libnet_convert_cp_state_to_string(cp_state));
252                 SECURE_CONNECTION_LOG(CONNECTION_INFO, "profile name: %s", event_cb->ProfileName);
253
254                 __libnet_state_changed_cb(event_cb->ProfileName, cp_state);
255
256                 break;
257         case NET_EVENT_CELLULAR_SET_DEFAULT_RSP:
258                 result = __libnet_convert_to_cp_error_type(event_cb->Error);
259                 CONNECTION_LOG(CONNECTION_INFO, "Got set default profile RSP %d", result);
260                 if (conn_handle->set_default_callback) {
261                         conn_handle->set_default_callback(result,
262                                 conn_handle->set_default_user_data);
263
264                         conn_handle->set_default_callback = NULL;
265                         conn_handle->set_default_user_data = NULL;
266                 }
267                 break;
268         case NET_EVENT_CELLULAR_RESET_DEFAULT_RSP:
269                 result = __libnet_convert_to_cp_error_type(event_cb->Error);
270                 CONNECTION_LOG(CONNECTION_INFO, "Got reset default profile RSP %d", result);
271                 if (conn_handle->reset_callback) {
272                         conn_handle->reset_callback(result,
273                                 conn_handle->reset_user_data);
274
275                         conn_handle->reset_callback = NULL;
276                         conn_handle->reset_user_data = NULL;
277                 }
278                 break;
279         case NET_EVENT_ETHERNET_CABLE_ATTACHED:
280                 CONNECTION_LOG(CONNECTION_INFO, "Got Ethernet cable Attached Indication\n");
281                 if (conn_handle->ethernet_cable_state_changed_callback) {
282                         conn_handle->ethernet_cable_state_changed_callback(CONNECTION_ETHERNET_CABLE_ATTACHED,
283                                 conn_handle->ethernet_cable_state_changed_user_data);
284                 }
285                 break;
286         case NET_EVENT_ETHERNET_CABLE_DETACHED:
287                 CONNECTION_LOG(CONNECTION_INFO, "Got Ethernet cable detached Indication\n");
288                 if (conn_handle->ethernet_cable_state_changed_callback) {
289                         conn_handle->ethernet_cable_state_changed_callback(CONNECTION_ETHERNET_CABLE_DETACHED,
290                                 conn_handle->ethernet_cable_state_changed_user_data);
291                 }
292                 break;
293         case NET_EVENT_NETWORK_TYPE_CHANGED:
294                 CONNECTION_LOG(CONNECTION_INFO, "Got Network Type Changed Indication");
295                 int *state = (int *) event_cb->Data;
296                 if (conn_handle->type_changed_callback) {
297                         int type = CONNECTION_TYPE_DISCONNECTED;
298
299                         switch (*state) {
300                         case VCONFKEY_NETWORK_CELLULAR:
301                                 type = CONNECTION_TYPE_CELLULAR;
302                                 break;
303                         case VCONFKEY_NETWORK_WIFI:
304                                 type = CONNECTION_TYPE_WIFI;
305                                 break;
306                         case VCONFKEY_NETWORK_ETHERNET:
307                                 type = CONNECTION_TYPE_ETHERNET;
308                                 break;
309                         case VCONFKEY_NETWORK_BLUETOOTH:
310                                 type = CONNECTION_TYPE_BT;
311                                 break;
312                         case VCONFKEY_NETWORK_DEFAULT_PROXY:
313                                 type = CONNECTION_TYPE_NET_PROXY;
314                                 break;
315                         default:
316                                 type = CONNECTION_TYPE_DISCONNECTED;
317                                 break;
318                         }
319
320                         conn_handle->type_changed_callback(type,
321                                 conn_handle->type_changed_user_data);
322                 }
323                 break;
324         case NET_EVENT_IPV4_ADDRESS_CHANGED:
325                 CONNECTION_LOG(CONNECTION_INFO, "Got IPv4 Address Changed Indication");
326                 if (conn_handle->ip_changed_callback) {
327                         char *ipv4_addr = NULL;
328                         char *ipv6_addr = NULL;
329                         char *addr = (char *)event_cb->Data;
330
331                         ipv4_addr = g_strdup(addr);
332                         ipv6_addr = vconf_get_str(VCONFKEY_NETWORK_IP6);
333                         if (ipv6_addr == NULL)
334                                 CONNECTION_LOG(CONNECTION_ERROR, //LCOV_EXCL_LINE
335                                                 "vconf_get_str(VCONFKEY_NETWORK_IP6) failed");
336
337                         conn_handle->ip_changed_callback(ipv4_addr, ipv6_addr,
338                                 conn_handle->ip_changed_user_data);
339
340                         g_free(ipv4_addr);
341                         g_free(ipv6_addr);
342                 }
343                 break;
344         case NET_EVENT_IPV6_ADDRESS_CHANGED:
345                 CONNECTION_LOG(CONNECTION_INFO, "Got IPv6 Address Changed Indication");
346                 if (conn_handle->ip_changed_callback) {
347                         char *ipv4_addr = NULL;
348                         char *ipv6_addr = NULL;
349                         char *addr = (char *)event_cb->Data;
350
351                         ipv6_addr = g_strdup(addr);
352                         ipv4_addr = vconf_get_str(VCONFKEY_NETWORK_IP);
353                         if (ipv4_addr == NULL)
354                                 CONNECTION_LOG(CONNECTION_ERROR, //LCOV_EXCL_LINE
355                                                 "vconf_get_str(VCONFKEY_NETWORK_IP) failed");
356
357                         conn_handle->ip_changed_callback(ipv4_addr, ipv6_addr,
358                                 conn_handle->ip_changed_user_data);
359
360                         g_free(ipv4_addr);
361                         g_free(ipv6_addr);
362                 }
363                 break;
364         case NET_EVENT_PROXY_ADDRESS_CHANGED:
365                 CONNECTION_LOG(CONNECTION_INFO, "Got Proxy Changed Indication");
366                 char *proxy_addr = (char *)event_cb->Data;
367
368                 if (conn_handle->proxy_changed_callback) {
369                         conn_handle->proxy_changed_callback(proxy_addr, NULL,
370                                 conn_handle->proxy_changed_user_data);
371                 }
372                 break;
373
374         default:
375                 break;
376         }
377 }
378 //LCOV_EXCL_STOP
379
380 static int __libnet_get_connected_count(struct _profile_list_s *profile_list)
381 {
382         int count = 0;
383         int i = 0;
384
385         for (; i < profile_list->count; i++) {
386                 if (profile_list->profiles[i].ProfileState == NET_STATE_TYPE_ONLINE ||
387                     profile_list->profiles[i].ProfileState == NET_STATE_TYPE_READY)
388                         count++;
389         }
390
391         return count;
392 }
393
394 static void __libnet_copy_connected_profile(net_profile_info_t **dest, struct _profile_list_s *source)
395 {
396         int i = 0;
397
398         for (; i < source->count; i++) {
399                 if (source->profiles[i].ProfileState == NET_STATE_TYPE_ONLINE ||
400                     source->profiles[i].ProfileState == NET_STATE_TYPE_READY) {
401                         memcpy(*dest, &source->profiles[i], sizeof(net_profile_info_t));
402                         (*dest)++;
403                 }
404         }
405 }
406
407 //LCOV_EXCL_START
408 static int __libnet_get_default_count(struct _profile_list_s *profile_list)
409 {
410         int count = 0;
411         int i = 0;
412
413         for (; i < profile_list->count; i++) {
414                 if (profile_list->profiles[i].profile_type == NET_DEVICE_CELLULAR) {
415                         if (profile_list->profiles[i].ProfileInfo.Pdp.DefaultConn == TRUE)
416                                 count++;
417                 }
418         }
419
420         return count;
421 }
422
423 static void __libnet_copy_default_profile(net_profile_info_t **dest, struct _profile_list_s *source)
424 {
425         int i = 0;
426
427         for (; i < source->count; i++) {
428                 if (source->profiles[i].profile_type == NET_DEVICE_CELLULAR) {
429                         if (source->profiles[i].ProfileInfo.Pdp.DefaultConn == TRUE) {
430                                 memcpy(*dest, &source->profiles[i], sizeof(net_profile_info_t));
431                                 (*dest)++;
432                         }
433                 }
434         }
435 }
436 //LCOV_EXCL_STOP
437
438 int _connection_libnet_init(connection_handle_s *conn_handle)
439 {
440         int rv;
441
442         rv = net_register_client(&(conn_handle->network_info_handle),
443                                 (net_event_cb_t)__libnet_evt_cb, conn_handle);
444         if (rv != NET_ERR_NONE)
445                 return rv;
446
447         if (profile_cb_table == NULL)
448                 profile_cb_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
449
450         return NET_ERR_NONE;
451 }
452
453 bool _connection_libnet_deinit(connection_handle_s *conn_handle)
454 {
455         net_deregister_client(conn_handle->network_info_handle);
456
457         if (profile_cb_table) {
458                 g_hash_table_destroy(profile_cb_table);
459                 profile_cb_table = NULL;
460         }
461
462         __libnet_clear_profile_list(&profile_iterator);
463
464         if (prof_handle_list) {
465                 g_slist_free_full(prof_handle_list, g_free);
466                 prof_handle_list = NULL;
467         }
468
469         return true;
470 }
471
472 void _connection_set_cs_tid(int tid, connection_handle_s *conn_handle)
473 {
474         net_set_cs_tid(tid, conn_handle->network_info_handle);
475 }
476
477 void _connection_unset_cs_tid(int tid, connection_handle_s *conn_handle)
478 {
479         net_unset_cs_tid(tid, conn_handle->network_info_handle);
480 }
481
482 bool _connection_libnet_check_profile_validity(connection_profile_h profile)
483 {
484         GSList *list;
485         int i = 0;
486
487         if (profile == NULL)
488                 return false;
489
490         for (list = prof_handle_list; list; list = list->next)
491                 if (profile == list->data) return true;
492
493         for (; i < profile_iterator.count; i++)
494                 if (profile == &profile_iterator.profiles[i]) return true;
495
496         return false;
497 }
498
499 int _connection_libnet_get_metered_state(connection_handle_s *conn_handle, bool* is_metered)
500 {
501         int rv = 0;
502         int status = 0;
503
504         rv = net_get_metered_state(conn_handle->network_info_handle, &status);
505         if (rv == NET_ERR_ACCESS_DENIED) {
506                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
507                 return CONNECTION_ERROR_PERMISSION_DENIED;
508         } else if (rv != NET_ERR_NONE) {
509                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get metered state[%d]", rv);
510                 return CONNECTION_ERROR_OPERATION_FAILED;
511         }
512
513         if (status == 1)
514                 *is_metered = true;
515         else
516                 *is_metered = false;
517         return CONNECTION_ERROR_NONE;
518 }
519
520 int _connection_libnet_get_wifi_state(connection_handle_s *conn_handle, connection_wifi_state_e *state)
521 {
522         int rv;
523         net_wifi_state_t wlan_state;
524
525         rv = net_get_wifi_state(conn_handle->network_info_handle, &wlan_state);
526         if (rv == NET_ERR_ACCESS_DENIED) {
527                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
528                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
529         } else if (rv != NET_ERR_NONE) {
530                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get Wi-Fi state[%d]", rv); //LCOV_EXCL_LINE
531                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
532         }
533
534         switch (wlan_state) {
535         case WIFI_OFF:
536                 *state = CONNECTION_WIFI_STATE_DEACTIVATED;
537                 break;
538         case WIFI_ON:
539         case WIFI_ASSOCIATION:
540         case WIFI_CONFIGURATION:
541                 *state = CONNECTION_WIFI_STATE_DISCONNECTED;
542                 break;
543         case WIFI_CONNECTED:
544         case WIFI_DISCONNECTING:
545                 *state = CONNECTION_WIFI_STATE_CONNECTED;
546                 break;
547         default:
548                 CONNECTION_LOG(CONNECTION_ERROR, "Unknown Wi-Fi state"); //LCOV_EXCL_LINE
549                 return CONNECTION_ERROR_INVALID_OPERATION; //LCOV_EXCL_LINE
550         }
551
552         return CONNECTION_ERROR_NONE;
553 }
554
555 //LCOV_EXCL_START
556 int _connection_libnet_get_ethernet_state(connection_handle_s *conn_handle,
557                         connection_ethernet_state_e *state)
558 {
559         int rv;
560         struct _profile_list_s ethernet_profiles = {0, 0, NULL};
561         rv = net_get_profile_list(conn_handle->network_info_handle,
562                         NET_DEVICE_ETHERNET, &ethernet_profiles.profiles,
563                         &ethernet_profiles.count);
564         if (rv == NET_ERR_ACCESS_DENIED) {
565                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
566                 return CONNECTION_ERROR_PERMISSION_DENIED;
567         }
568
569         if (ethernet_profiles.count == 0) {
570                 *state = CONNECTION_ETHERNET_STATE_DEACTIVATED;
571                 return CONNECTION_ERROR_NONE;
572         }
573
574         switch (ethernet_profiles.profiles->ProfileState) {
575         case NET_STATE_TYPE_ONLINE:
576         case NET_STATE_TYPE_READY:
577                 *state = CONNECTION_ETHERNET_STATE_CONNECTED;
578                 break;
579         case NET_STATE_TYPE_IDLE:
580         case NET_STATE_TYPE_FAILURE:
581         case NET_STATE_TYPE_ASSOCIATION:
582         case NET_STATE_TYPE_CONFIGURATION:
583         case NET_STATE_TYPE_DISCONNECT:
584                 *state = CONNECTION_ETHERNET_STATE_DISCONNECTED;
585                 break;
586         default:
587                 __libnet_clear_profile_list(&ethernet_profiles);
588                 return CONNECTION_ERROR_OPERATION_FAILED;
589         }
590
591         __libnet_clear_profile_list(&ethernet_profiles);
592
593         return CONNECTION_ERROR_NONE;
594 }
595
596 int _connection_libnet_get_ethernet_cable_state(connection_handle_s *conn_handle,
597                         connection_ethernet_cable_state_e* state)
598 {
599         int rv = 0;
600         int status = 0;
601
602         rv = net_get_ethernet_cable_state(conn_handle->network_info_handle, &status);
603         if (rv == NET_ERR_ACCESS_DENIED) {
604                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
605                 return CONNECTION_ERROR_PERMISSION_DENIED;
606         } else if (rv != NET_ERR_NONE) {
607                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get ethernet cable state[%d]", rv);
608                 return CONNECTION_ERROR_OPERATION_FAILED;
609         }
610
611         if (status == 1)
612                 *state = CONNECTION_ETHERNET_CABLE_ATTACHED;
613         else
614                 *state = CONNECTION_ETHERNET_CABLE_DETACHED;
615         return CONNECTION_ERROR_NONE;
616 }
617 //LCOV_EXCL_STOP
618
619 int _connection_libnet_get_bluetooth_state(connection_handle_s *conn_handle, connection_bt_state_e *state)
620 {
621         int i = 0;
622         int rv = 0;
623         struct _profile_list_s bluetooth_profiles = {0, 0, NULL};
624         rv = net_get_profile_list(conn_handle->network_info_handle,
625                         NET_DEVICE_BLUETOOTH, &bluetooth_profiles.profiles,
626                         &bluetooth_profiles.count);
627         if (rv == NET_ERR_ACCESS_DENIED) {
628                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
629                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
630         }
631
632         if (bluetooth_profiles.count == 0) {
633                 *state = CONNECTION_BT_STATE_DEACTIVATED;
634                 return CONNECTION_ERROR_NONE;
635         }
636
637         //LCOV_EXCL_START
638         for (; i < bluetooth_profiles.count; i++) {
639                 switch (bluetooth_profiles.profiles[i].ProfileState) {
640                 case NET_STATE_TYPE_ONLINE:
641                 case NET_STATE_TYPE_READY:
642                         *state = CONNECTION_BT_STATE_CONNECTED;
643                         goto done;
644                 case NET_STATE_TYPE_IDLE:
645                 case NET_STATE_TYPE_FAILURE:
646                 case NET_STATE_TYPE_ASSOCIATION:
647                 case NET_STATE_TYPE_CONFIGURATION:
648                 case NET_STATE_TYPE_DISCONNECT:
649                         *state = CONNECTION_BT_STATE_DISCONNECTED;
650                         break;
651                 default:
652                         __libnet_clear_profile_list(&bluetooth_profiles);
653                         return CONNECTION_ERROR_OPERATION_FAILED;
654                 }
655         }
656         //LCOV_EXCL_STOP
657
658 done:
659         __libnet_clear_profile_list(&bluetooth_profiles);
660
661         return CONNECTION_ERROR_NONE;
662 }
663
664 int _connection_libnet_get_profile_iterator(connection_handle_s *conn_handle,
665                         connection_iterator_type_e type, connection_profile_iterator_h* profile_iter_h)
666 {
667         int count = 0;
668         int rv;
669         net_profile_info_t *profiles = NULL;
670
671         struct _profile_list_s profile_list = {0, 0, NULL};
672
673         __libnet_clear_profile_list(&profile_iterator);
674
675         rv = net_get_all_profile_list(conn_handle->network_info_handle,
676                         &profile_list.profiles, &profile_list.count);
677         if (rv == NET_ERR_ACCESS_DENIED) {
678                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
679                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
680         } else if (rv != NET_ERR_NO_SERVICE && rv != NET_ERR_NONE)
681                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
682
683         *profile_iter_h = &profile_iterator;
684
685         switch (type) {
686         case CONNECTION_ITERATOR_TYPE_REGISTERED:
687                 count = profile_list.count;
688                 CONNECTION_LOG(CONNECTION_INFO, "Total profile count : %d", count);
689                 if (count == 0)
690                         return CONNECTION_ERROR_NONE;
691
692                 profiles = g_try_new0(net_profile_info_t, count);
693                 if (profiles == NULL) {
694                         __libnet_clear_profile_list(&profile_list);
695                         return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
696                 }
697
698                 profile_iterator.profiles = profiles;
699
700                 memcpy(profiles, profile_list.profiles, sizeof(net_profile_info_t) * count);
701
702                 break;
703         case CONNECTION_ITERATOR_TYPE_CONNECTED:
704                 count = __libnet_get_connected_count(&profile_list);
705                 CONNECTION_LOG(CONNECTION_INFO, "Total connected profile count : %d", count);
706                 if (count == 0)
707                         return CONNECTION_ERROR_NONE;
708
709                 profiles = g_try_new0(net_profile_info_t, count);
710                 if (profiles == NULL) {
711                         __libnet_clear_profile_list(&profile_list);
712                         return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
713                 }
714
715                 profile_iterator.profiles = profiles;
716
717                 __libnet_copy_connected_profile(&profiles, &profile_list);
718
719                 break;
720         case CONNECTION_ITERATOR_TYPE_DEFAULT:
721                 count = __libnet_get_default_count(&profile_list);
722                 CONNECTION_LOG(CONNECTION_INFO, "Total default profile count : %d", count); //LCOV_EXCL_LINE
723                 if (count == 0)
724                         return CONNECTION_ERROR_NONE;
725
726                 profiles = g_try_new0(net_profile_info_t, count);
727                 if (profiles == NULL) {
728                         __libnet_clear_profile_list(&profile_list);
729                         return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
730                 }
731
732                 profile_iterator.profiles = profiles;
733
734                 __libnet_copy_default_profile(&profiles, &profile_list);
735
736                 break;
737         }
738
739         __libnet_clear_profile_list(&profile_list);
740
741         profile_iterator.count = count;
742
743         return CONNECTION_ERROR_NONE;
744 }
745
746 int _connection_libnet_get_iterator_next(connection_profile_iterator_h profile_iter_h, connection_profile_h *profile)
747 {
748         if (profile_iter_h != &profile_iterator)
749                 return CONNECTION_ERROR_INVALID_PARAMETER;
750
751         if (profile_iterator.count <= profile_iterator.next)
752                 return CONNECTION_ERROR_ITERATOR_END;
753
754         *profile = &profile_iterator.profiles[profile_iterator.next];
755         profile_iterator.next++;
756
757         return CONNECTION_ERROR_NONE;
758 }
759
760 bool _connection_libnet_iterator_has_next(connection_profile_iterator_h profile_iter_h)
761 {
762         if (profile_iter_h != &profile_iterator)
763                 return false;
764
765         if (profile_iterator.count <= profile_iterator.next)
766                 return false;
767
768         return true;
769 }
770
771 int _connection_libnet_destroy_iterator(connection_profile_iterator_h profile_iter_h)
772 {
773         if (profile_iter_h != &profile_iterator)
774                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
775
776         __libnet_clear_profile_list(&profile_iterator);
777
778         return CONNECTION_ERROR_NONE;
779 }
780
781 int _connection_libnet_get_current_profile(connection_handle_s *conn_handle,
782                         connection_profile_h *profile)
783 {
784         net_profile_info_t active_profile;
785         int rv;
786
787         rv = net_get_active_net_info(conn_handle->network_info_handle, &active_profile);
788         if (rv == NET_ERR_NO_SERVICE)
789                 return CONNECTION_ERROR_NO_CONNECTION; //LCOV_EXCL_LINE
790         else if (rv == NET_ERR_ACCESS_DENIED) {
791                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
792                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
793         } else if (rv != NET_ERR_NONE)
794                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
795
796         *profile = g_try_malloc0(sizeof(net_profile_info_t));
797         if (*profile == NULL)
798                 return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
799
800         memcpy(*profile, &active_profile, sizeof(net_profile_info_t));
801         prof_handle_list = g_slist_append(prof_handle_list, *profile);
802
803         return CONNECTION_ERROR_NONE;
804 }
805
806 int _connection_libnet_reset_profile(connection_handle_s *conn_handle,
807                 connection_reset_option_e type, connection_cellular_subscriber_id_e id)
808 {
809         int rv;
810
811         rv = net_reset_profile(conn_handle->network_info_handle, type, id);
812         if (rv == NET_ERR_ACCESS_DENIED)
813                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
814         else if (rv != NET_ERR_NONE)
815                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
816
817         return CONNECTION_ERROR_NONE;
818 }
819
820 int _connection_libnet_open_profile(connection_handle_s *conn_handle,
821                         connection_profile_h profile)
822 {
823         int rv;
824
825         if (!(_connection_libnet_check_profile_validity(profile))) {
826                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
827                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
828         }
829
830         net_profile_info_t *profile_info = profile;
831
832         if (profile_info->profile_type == NET_DEVICE_MESH)
833                 rv = net_open_mesh_connection_with_profile(conn_handle->network_info_handle,
834                                 profile_info->ProfileName);
835         else
836                 rv = net_open_connection_with_profile(conn_handle->network_info_handle,
837                                 profile_info->ProfileName);
838
839         if (rv == NET_ERR_ACCESS_DENIED)
840                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
841         else if (rv != NET_ERR_NONE)
842                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
843
844         return CONNECTION_ERROR_NONE;
845 }
846
847 int _connection_libnet_get_cellular_service_profile(connection_handle_s *conn_handle,
848                 connection_cellular_service_type_e type, connection_profile_h *profile)
849 {
850         int i = 0, j = 0;
851         int rv = NET_ERR_NONE;
852 #if defined TIZEN_DUALSIM_ENABLE
853         int default_subscriber_id = 0;
854         char subscriber_id[3];
855 #endif
856
857         struct _profile_list_s cellular_profiles = { 0, 0, NULL };
858         net_service_type_t service_type = _connection_profile_convert_to_libnet_cellular_service_type(type);
859
860         rv = net_get_profile_list(conn_handle->network_info_handle,
861                         NET_DEVICE_CELLULAR, &cellular_profiles.profiles,
862                         &cellular_profiles.count);
863         if (rv == NET_ERR_ACCESS_DENIED) {
864                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
865                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
866         } else if (rv != NET_ERR_NONE) {
867                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get profile list (%d)", rv); //LCOV_EXCL_LINE
868                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
869         }
870
871 #if defined TIZEN_DUALSIM_ENABLE
872         if (vconf_get_int(VCONF_TELEPHONY_DEFAULT_DATA_SERVICE,
873                                                 &default_subscriber_id) != 0) {
874                 CONNECTION_LOG(CONNECTION_ERROR,
875                                                 "Failed to get VCONF_TELEPHONY_DEFAULT_DATA_SERVICE");
876                 __libnet_clear_profile_list(&cellular_profiles); //LCOV_EXCL_LINE
877                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
878         }
879
880         g_snprintf(subscriber_id, sizeof(subscriber_id), "%d", default_subscriber_id);
881 #endif
882
883         for (i = 0; i < cellular_profiles.count; i++)
884                 if (cellular_profiles.profiles[i].ProfileInfo.Pdp.ServiceType == service_type)
885 #if defined TIZEN_DUALSIM_ENABLE
886                         if (g_str_has_suffix(
887                                         cellular_profiles.profiles[i].ProfileInfo.Pdp.PSModemPath,
888                                         subscriber_id) == TRUE)
889 #endif
890                                 break;
891
892         if (i >= cellular_profiles.count) {
893                 __libnet_clear_profile_list(&cellular_profiles); //LCOV_EXCL_LINE
894                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
895         }
896
897         *profile = g_try_malloc0(sizeof(net_profile_info_t));
898         if (*profile == NULL) {
899                 __libnet_clear_profile_list(&cellular_profiles); //LCOV_EXCL_LINE
900                 return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
901         }
902
903         memcpy(*profile, &cellular_profiles.profiles[i], sizeof(net_profile_info_t));
904
905         if (cellular_profiles.profiles[i].ProfileInfo.Pdp.DefaultConn)
906                 goto done;
907
908         //LCOV_EXCL_START
909         if (type != CONNECTION_CELLULAR_SERVICE_TYPE_INTERNET &&
910             type != CONNECTION_CELLULAR_SERVICE_TYPE_PREPAID_INTERNET)
911                 goto done;
912
913         for (j = 0; j < cellular_profiles.count; j++) {
914                 if (i == j)
915                         continue;
916
917                 if (cellular_profiles.profiles[j].ProfileInfo.Pdp.ServiceType != service_type)
918                         continue;
919
920                 if (cellular_profiles.profiles[j].ProfileInfo.Pdp.DefaultConn) {
921                         memcpy(*profile, &cellular_profiles.profiles[j], sizeof(net_profile_info_t));
922                         goto done;
923                 }
924         }
925         //LCOV_EXCL_STOP
926
927 done:
928         __libnet_clear_profile_list(&cellular_profiles);
929         prof_handle_list = g_slist_append(prof_handle_list, *profile);
930
931         return CONNECTION_ERROR_NONE;
932 }
933
934 int _connection_libnet_set_cellular_service_profile_sync(connection_handle_s *conn_handle,
935                         connection_cellular_service_type_e type, connection_profile_h profile)
936 {
937         int rv;
938
939         if (!(_connection_libnet_check_profile_validity(profile))) {
940                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
941                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
942         }
943
944         net_profile_info_t *profile_info = profile;
945         connection_cellular_service_type_e service_type;
946
947         service_type = _profile_convert_to_connection_cellular_service_type(profile_info->ProfileInfo.Pdp.ServiceType);
948
949         if (service_type != type)
950                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
951
952         rv = net_set_default_cellular_service_profile(conn_handle->network_info_handle,
953                                 profile_info->ProfileName);
954         if (rv == NET_ERR_ACCESS_DENIED) {
955                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
956                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
957         } else if (rv != NET_ERR_NONE)
958                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
959
960         return CONNECTION_ERROR_NONE;
961 }
962
963 int _connection_libnet_set_cellular_service_profile_async(connection_handle_s *conn_handle,
964                         connection_cellular_service_type_e type, connection_profile_h profile)
965 {
966         int rv;
967
968         if (!(_connection_libnet_check_profile_validity(profile))) {
969                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
970                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
971         }
972
973         net_profile_info_t *profile_info = profile;
974         connection_cellular_service_type_e service_type;
975
976         service_type = _profile_convert_to_connection_cellular_service_type(profile_info->ProfileInfo.Pdp.ServiceType);
977
978         if (service_type != type)
979                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
980
981         rv = net_set_default_cellular_service_profile_async(conn_handle->network_info_handle,
982                                 profile_info->ProfileName);
983         if (rv == NET_ERR_ACCESS_DENIED) {
984                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
985         } else if (rv != NET_ERR_NONE)
986                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
987
988         return CONNECTION_ERROR_NONE;
989 }
990
991 int _connection_libnet_close_profile(connection_handle_s *conn_handle, connection_profile_h profile)
992 {
993         int rv;
994
995         if (!(_connection_libnet_check_profile_validity(profile))) {
996                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
997                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
998         }
999
1000         net_profile_info_t *profile_info = profile;
1001
1002         if (profile_info->profile_type == NET_DEVICE_MESH)
1003                 rv = net_close_mesh_connection(conn_handle->network_info_handle, profile_info->ProfileName);
1004         else
1005                 rv = net_close_connection(conn_handle->network_info_handle, profile_info->ProfileName);
1006
1007         if (rv == NET_ERR_ACCESS_DENIED)
1008                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1009         else if (rv != NET_ERR_NONE)
1010                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1011
1012         return CONNECTION_ERROR_NONE;
1013 }
1014
1015 int _connection_libnet_add_route(connection_handle_s *conn_handle,
1016                         const char *interface_name, const char *host_address)
1017 {
1018         int rv;
1019         char *endstr = NULL;
1020         int address_family = 0;
1021
1022         address_family = AF_INET;
1023
1024         endstr = strrchr(host_address, '.');
1025         if (endstr == NULL ||
1026                         strcmp(endstr, ".0") == 0 ||
1027                         strncmp(host_address, "0.", 2) == 0 ||
1028                         strstr(host_address, "255") != NULL) {
1029                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1030                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1031         }
1032
1033         rv = net_add_route(conn_handle->network_info_handle,
1034                                 host_address, interface_name, address_family);
1035         if (rv == NET_ERR_ACCESS_DENIED) {
1036                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1037                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1038         } else if (rv != NET_ERR_NONE)
1039                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1040
1041         return CONNECTION_ERROR_NONE;
1042 }
1043
1044 int _connection_libnet_remove_route(connection_handle_s *conn_handle,
1045                         const char *interface_name, const char *host_address)
1046 {
1047         int rv;
1048         char *endstr = strrchr(host_address, '.');
1049         int address_family = 0;
1050
1051         address_family = AF_INET;
1052
1053         endstr = strrchr(host_address, '.');
1054         if (endstr == NULL ||
1055                 strcmp(endstr, ".0") == 0 ||
1056                 strncmp(host_address, "0.", 2) == 0 ||
1057                 strstr(host_address, ".0.") != NULL || strstr(host_address, "255") != NULL) {
1058                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed"); //LCOV_EXCL_LINE
1059                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1060         }
1061
1062         rv = net_remove_route(conn_handle->network_info_handle,
1063                                 host_address, interface_name, address_family);
1064         if (rv == NET_ERR_ACCESS_DENIED) {
1065                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1066                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1067         } else if (rv != NET_ERR_NONE)
1068                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1069
1070         return CONNECTION_ERROR_NONE;
1071 }
1072
1073 int _connection_libnet_add_route_ipv6(connection_handle_s *conn_handle,
1074                         const char *interface_name, const char *host_address, const char *gateway)
1075 {
1076         int rv;
1077         int address_family = 0;
1078
1079         address_family = AF_INET6;
1080
1081         if (strncmp(host_address, "fe80:", 5) == 0 ||
1082                 strncmp(host_address, "ff00:", 5) == 0 ||
1083                 strncmp(host_address, "::", 2) == 0) {
1084                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1085                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1086         }
1087
1088         rv = net_add_route_ipv6(conn_handle->network_info_handle,
1089                                 host_address, interface_name, address_family, gateway);
1090         if (rv == NET_ERR_ACCESS_DENIED) {
1091                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1092                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1093         } else if (rv != NET_ERR_NONE)
1094                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1095
1096         return CONNECTION_ERROR_NONE;
1097 }
1098
1099 int _connection_libnet_remove_route_ipv6(connection_handle_s *conn_handle,
1100                         const char *interface_name, const char *host_address, const char *gateway)
1101 {
1102         int rv;
1103         int address_family = 0;
1104
1105         address_family = AF_INET6;
1106
1107         if (strncmp(host_address, "fe80:", 5) == 0 ||
1108                 strncmp(host_address, "ff00:", 5) == 0 ||
1109                 strncmp(host_address, "::", 2) == 0) {
1110                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1111                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1112         }
1113
1114         rv = net_remove_route_ipv6(conn_handle->network_info_handle,
1115                                 host_address, interface_name, address_family, gateway);
1116         if (rv == NET_ERR_ACCESS_DENIED) {
1117                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1118                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1119         } else if (rv != NET_ERR_NONE)
1120                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1121
1122         return CONNECTION_ERROR_NONE;
1123 }
1124
1125 int _connection_libnet_add_route_entry(connection_handle_s *conn_handle,
1126                 connection_address_family_e address_family, const char *interface_name,
1127                 const char *host_address, const char *gateway)
1128 {
1129         int rv;
1130         char *endstr = NULL;
1131         int address_family_type = 0;
1132
1133         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4)
1134                 address_family_type = AF_INET;
1135         else
1136                 address_family_type = AF_INET6;
1137
1138         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4) {
1139
1140                 endstr = strrchr(host_address, '.');
1141                 if (endstr == NULL ||
1142                                 strcmp(endstr, ".0") == 0 ||
1143                                 strncmp(host_address, "0.", 2) == 0 ||
1144                                 strstr(host_address, "255") != NULL) {
1145                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1146                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1147                 }
1148
1149                 rv = net_add_route_entry(conn_handle->network_info_handle,
1150                                 host_address, interface_name, address_family_type, gateway);
1151                 if (rv == NET_ERR_ACCESS_DENIED) {
1152                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1153                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1154                 } else if (rv != NET_ERR_NONE)
1155                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1156
1157         } else {
1158
1159                 if (strncmp(host_address, "fe80:", 5) == 0 ||
1160                         strncmp(host_address, "ff00:", 5) == 0 ||
1161                         strncmp(host_address, "::", 2) == 0) {
1162                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1163                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1164                 }
1165
1166                 rv = net_add_route_ipv6(conn_handle->network_info_handle,
1167                                 host_address, interface_name, address_family_type, gateway);
1168                 if (rv == NET_ERR_ACCESS_DENIED) {
1169                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1170                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1171                 } else if (rv != NET_ERR_NONE)
1172                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1173         }
1174
1175         return CONNECTION_ERROR_NONE;
1176 }
1177
1178 int _connection_libnet_remove_route_entry(connection_handle_s *conn_handle,
1179                 connection_address_family_e address_family, const char *interface_name,
1180                 const char *host_address, const char *gateway)
1181 {
1182         int rv;
1183         char *endstr = strrchr(host_address, '.');
1184         int address_family_type = 0;
1185
1186         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4)
1187                 address_family_type = AF_INET;
1188         else
1189                 address_family_type = AF_INET6;
1190
1191         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4) {
1192                 endstr = strrchr(host_address, '.');
1193                 if (endstr == NULL ||
1194                         strcmp(endstr, ".0") == 0 ||
1195                         strncmp(host_address, "0.", 2) == 0 ||
1196                         strstr(host_address, ".0.") != NULL || strstr(host_address, "255") != NULL) {
1197                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed"); //LCOV_EXCL_LINE
1198                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1199                 }
1200
1201                 rv = net_remove_route_entry(conn_handle->network_info_handle, host_address,
1202                                         interface_name, address_family_type, gateway);
1203                 if (rv == NET_ERR_ACCESS_DENIED) {
1204                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1205                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1206                 } else if (rv != NET_ERR_NONE)
1207                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1208
1209         } else {
1210
1211                 if (strncmp(host_address, "fe80:", 5) == 0 ||
1212                         strncmp(host_address, "ff00:", 5) == 0 ||
1213                         strncmp(host_address, "::", 2) == 0) {
1214                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1215                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1216                 }
1217
1218                 rv = net_remove_route_ipv6(conn_handle->network_info_handle, host_address,
1219                                         interface_name, address_family_type, gateway);
1220                 if (rv == NET_ERR_ACCESS_DENIED) {
1221                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1222                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1223                 } else if (rv != NET_ERR_NONE)
1224                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1225         }
1226
1227         return CONNECTION_ERROR_NONE;
1228 }
1229
1230 void _connection_libnet_add_to_profile_list(connection_profile_h profile)
1231 {
1232         prof_handle_list = g_slist_append(prof_handle_list, profile);
1233 }
1234
1235 void _connection_libnet_remove_from_profile_list(connection_profile_h profile)
1236 {
1237         prof_handle_list = g_slist_remove(prof_handle_list, profile);
1238         g_free(profile);
1239 }
1240
1241 bool _connection_libnet_add_to_profile_cb_list(connection_profile_h profile,
1242                 connection_profile_state_changed_cb callback, void *user_data)
1243 {
1244         net_profile_info_t *profile_info = profile;
1245         char *profile_name = g_strdup(profile_info->ProfileName);
1246
1247         struct _profile_cb_s *profile_cb_info = g_try_malloc0(sizeof(struct _profile_cb_s));
1248         if (profile_cb_info == NULL) {
1249                 g_free(profile_name); //LCOV_EXCL_LINE
1250                 return false; //LCOV_EXCL_LINE
1251         }
1252
1253         profile_cb_info->callback = callback;
1254         profile_cb_info->user_data = user_data;
1255         profile_cb_info->state = _profile_convert_to_cp_state(profile_info->ProfileState);
1256
1257         g_hash_table_replace(profile_cb_table, profile_name, profile_cb_info);
1258
1259         return true;
1260 }
1261
1262 bool _connection_libnet_remove_from_profile_cb_list(connection_profile_h profile)
1263 {
1264         net_profile_info_t *profile_info = profile;
1265
1266         if (g_hash_table_remove(profile_cb_table, profile_info->ProfileName) == TRUE)
1267                 return true;
1268
1269         return false; //LCOV_EXCL_LINE
1270 }
1271
1272 int _connection_libnet_set_statistics(connection_handle_s *conn_handle,
1273                         net_device_t device_type, net_statistics_type_e statistics_type)
1274 {
1275         int rv;
1276         rv = net_set_statistics(conn_handle->network_info_handle,
1277                                 device_type, statistics_type);
1278         if (rv == NET_ERR_ACCESS_DENIED) {
1279                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1280                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1281         } else if (rv != NET_ERR_NONE)
1282                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1283
1284         return CONNECTION_ERROR_NONE;
1285 }
1286
1287 int _connection_libnet_get_statistics(connection_handle_s *conn_handle,
1288                         net_statistics_type_e statistics_type, unsigned long long *size)
1289 {
1290         int rv;
1291         rv = net_get_statistics(conn_handle->network_info_handle,
1292                                 NET_DEVICE_WIFI, statistics_type, size);
1293         if (rv == NET_ERR_ACCESS_DENIED) {
1294                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1295                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1296         } else if (rv != NET_ERR_NONE)
1297                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1298
1299         return CONNECTION_ERROR_NONE;
1300 }
1301
1302 int _connection_libnet_set_cellular_subscriber_id(connection_profile_h profile,
1303                 connection_cellular_subscriber_id_e sim_id)
1304 {
1305         char *modem_path = NULL;
1306         net_profile_info_t *profile_info = (net_profile_info_t *)profile;
1307
1308         if (net_get_cellular_modem_object_path(&modem_path, sim_id) != NET_ERR_NONE) {
1309                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get subscriber[%d]", sim_id); //LCOV_EXCL_LINE
1310                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1311         }
1312
1313         if (!modem_path) {
1314                 CONNECTION_LOG(CONNECTION_ERROR, "NULL modem object path"); //LCOV_EXCL_LINE
1315                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1316         }
1317
1318         g_strlcpy(profile_info->ProfileInfo.Pdp.PSModemPath, modem_path,
1319                                 NET_PROFILE_NAME_LEN_MAX);
1320         g_free(modem_path);
1321
1322         return CONNECTION_ERROR_NONE;
1323 }
1324
1325 int _connection_libnet_check_get_privilege(void)
1326 {
1327         int rv;
1328
1329         rv = net_check_get_privilege();
1330         if (rv == NET_ERR_ACCESS_DENIED) {
1331                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1332                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1333         } else if (rv != NET_ERR_NONE)
1334                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1335
1336         return CONNECTION_ERROR_NONE;
1337 }
1338
1339 int _connection_libnet_check_profile_privilege(void)
1340 {
1341         int rv;
1342
1343         rv = net_check_profile_privilege();
1344         if (rv == NET_ERR_ACCESS_DENIED) {
1345                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1346                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1347         } else if (rv != NET_ERR_NONE)
1348                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1349
1350         return CONNECTION_ERROR_NONE;
1351 }
1352
1353 bool __libnet_check_feature_supported(const char *key, connection_supported_feature_e feature)
1354 {
1355         if (!connection_is_feature_checked[feature]) {
1356                 if (system_info_get_platform_bool(key, &connection_feature_supported[feature]) < 0) {
1357                         CONNECTION_LOG(CONNECTION_ERROR, "Error - Feature getting from System Info"); //LCOV_EXCL_LINE
1358                         set_last_result(CONNECTION_ERROR_OPERATION_FAILED); //LCOV_EXCL_LINE
1359                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1360                 }
1361                 connection_is_feature_checked[feature] = true;
1362         }
1363         return connection_feature_supported[feature];
1364 }
1365
1366 int _connection_check_feature_supported(const char *feature_name, ...)
1367 {
1368         va_list list;
1369         const char *key;
1370         bool value = false;
1371         bool feature_supported = false;
1372
1373         va_start(list, feature_name);
1374         key = feature_name;
1375         while (1) {
1376                 if (strcmp(key, TELEPHONY_FEATURE) == 0)
1377                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_TELEPHONY);
1378                 if (strcmp(key, WIFI_FEATURE) == 0)
1379                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_WIFI);
1380                 if (strcmp(key, TETHERING_BLUETOOTH_FEATURE) == 0)
1381                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_TETHERING_BLUETOOTH);
1382                 if (strcmp(key, ETHERNET_FEATURE) == 0)
1383                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_ETHERNET);
1384
1385                 feature_supported |= value;
1386                 key = va_arg(list, const char *);
1387                 if (!key) break;
1388         }
1389         if (!feature_supported) {
1390                 CONNECTION_LOG(CONNECTION_ERROR, "Error - Feature is not supported");
1391                 set_last_result(CONNECTION_ERROR_NOT_SUPPORTED);
1392                 va_end(list);
1393                 return CONNECTION_ERROR_NOT_SUPPORTED;
1394         }
1395
1396         va_end(list);
1397         set_last_result(CONNECTION_ERROR_NONE);
1398         return CONNECTION_ERROR_NONE;
1399 }
1400
1401 int _connection_libnet_start_tcpdump(connection_handle_s *conn_handle)
1402 {
1403         connection_error_e result = CONNECTION_ERROR_NONE;
1404         net_err_t ret = NET_ERR_NONE;
1405
1406         ret = net_start_tcpdump(conn_handle->network_info_handle);
1407         result = __libnet_convert_to_cp_error_type(ret);
1408
1409         return result;
1410 }
1411
1412 int _connection_libnet_stop_tcpdump(connection_handle_s *conn_handle)
1413 {
1414         connection_error_e result = CONNECTION_ERROR_NONE;
1415         net_err_t ret = NET_ERR_NONE;
1416
1417         ret = net_stop_tcpdump(conn_handle->network_info_handle);
1418         result = __libnet_convert_to_cp_error_type(ret);
1419
1420         return result;
1421 }
1422
1423 int _connection_libnet_get_tcpdump_state(connection_handle_s *conn_handle,
1424                         gboolean *tcpdump_state)
1425 {
1426         connection_error_e result = CONNECTION_ERROR_NONE;
1427         net_err_t ret = NET_ERR_NONE;
1428
1429         ret = net_get_tcpdump_state(conn_handle->network_info_handle, tcpdump_state);
1430         result = __libnet_convert_to_cp_error_type(ret);
1431
1432         return result;
1433 }
1434
1435 void _connection_lock(void)
1436 {
1437         pthread_mutex_lock(&g_conn_thread_mutex);
1438 }
1439
1440 void _connection_unlock(void)
1441 {
1442         pthread_mutex_unlock(&g_conn_thread_mutex);
1443 }